Shopify CAPI Setup

If you don't have a tracker or SignalSight account, you can check out our document here. If your account and tracker are ready, you can start to the Shopify CAPI implementation.


Once you have completed the steps to create a tracker, you can proceed to the CAPI installation step in Shopify. In this step, after determining the events you will use on your website, we can start the editing process. In this guide, we will cover the standard Facebook events:

  • Pageview
  • Viewcontent
  • AddtoCart
  • Search
  • InitiateCheckout
  • Purchase

To access the area where you can add the codes, follow these steps:

  1. Login to your Shopify admin account.
  2. In the left menu, under the Online Store section, click on "Themes."
  3. On the next screen, locate the "Customize" button next to the theme you want to edit and click on the three dots next to it.
  4. From the menu that appears, select "Edit Code." This will take you to the area where you can add the codes.

Note: Make sure to ensure that the necessary codes are placed correctly on the appropriate pages for the events to work. While the provided codes and pages mentioned below should work, occasionally there may be variations in design that could result in differences.


Pageview Event and Base Code

Since the Theme.liquid file is a file that is called on every page, we need to include the meta base code and SignalSight Loader code here. The user parameters included in the init code are valid for shopify users and their use is at your discretion.

<script>
    !function (f, b, e, v, n, t, s) {
      if (f.fbq) return; n = f.fbq = function () {
        if (arguments[1] === "Purchase" && typeof arguments[3]?.eventID === "undefined" && arguments[2]?.content_type !== "product") return;
        if (arguments[1] === "AddToCart" && typeof arguments[3]?.eventID === "undefined" && arguments[2]?.content_type !== "product") return;
        if (arguments[1] === "PageView" && typeof arguments[3]?.eventID === "undefined") return;
        if (arguments[1] === "Search" && typeof arguments[3]?.eventID === "undefined") return;
        if (arguments[1] === "ViewContent" && typeof arguments[3]?.eventID === "undefined" && arguments[2]?.content_type !== "product") return;
        n.callMethod ?
        n.callMethod.apply(n, arguments) : n.queue.push(arguments)
      };
    if (!f._fbq) f._fbq = n; n.push = n; n.loaded = !0; n.version = '2.0';
    n.queue = []; t = b.createElement(e); t.async = !0;
    t.src = v; s = b.head.getElementsByTagName(e)[0];
    s.parentNode.insertBefore(t, s)
  }(window, document, 'script',
    'https://connect.facebook.net/en_US/fbevents.js');
</script>
<script>
window.p2sq = window.p2sq || [];
    p2sq.push({et:'Init',p:{
      em: {% assign email_hash = customer.email | sha256 %} "{{ email_hash }}",
      ph: {% assign phone_hash = customer.phone | sha256 %} "{{ phone_hash }}",
      fn: {% assign firstname_hash = customer.first_name | sha256 %} "{{ firstname_hash }}",
      ln: {% assign lastname_hash = customer.last_name | sha256 %} "{{ lastname_hash }}"
    }});

    p2sq.push({et: 'PageView'});

    !function(f, b, e, v, t, s) {f.p2sq = f.p2sq || [];if (f.p2sf) return;f.p2sf=true;
    t = b.createElement(e);t.async = !0;t.src = v;s = b.getElementsByTagName(e)[0];
    s.parentNode.insertBefore(t, s);
    }(window,document,'script','https://cpi.ssevt.com/js/v4.2/your-alias-code');

</script>

ViewContent Event

(main-product.liquid)

The data you can automatically obtain in Shopify for ViewContent is as follows. In addition to these, you can add new parameters or go to edit these parameters. If you are printing parameters such as content_name to the DataLayer, you can use these parameters.

It will be enough to place the code below on the product.liquid or main-product.liquid page of your theme.

<script>
    p2sq.push({et: 'ViewContent', p: {
      content_ids: ['{{ product.id }}'],
      content_type: 'product', 
      value: {{ product.price | divided_by: 100.00 }},
      currency: 'USD'
    }});
</script>

Search Event

(main-search.liquid)

If you place the following code in the main-search.liquid file, you can send events to Facebook from both the browser and server. As an example, parameters like search_string and currency have been provided. You can update the search_string object based on your own dataLayer variable {{ search.terms }} to include the search made as an event parameter.

<script>
    p2sq.push({et: 'Search', p: {
        search_string: '{{ search.terms }}',
        currency: 'USD',
    }});
</script>

AddToCart Event

(product.liquid - main-product.liquid)

For AddtoCart event, you can include the following code in your product.liquid or main-product.liquid file in your design. The point to note here is that in most Shopify designs, the name tag of the add to cart button is "add", so this will be effective in triggering the add to cart process.

<script>
    document.querySelector('[name="add"]').addEventListener('click', function() {
      p2sq.push({
        et: 'AddToCart', p: {
        content_ids: ['{{ product.id }}'],
        content_type: 'product',
        value: {{ product.price | divided_by: 100.00 }},
        currency: 'USD',
      }});
    });
</script>

InitiateCheckout Event

(cart.liquid - main-cart.liquid)

This code example is written using Shopify's Liquid templating language and creates a content_ids array that includes the IDs of each product line item. It also sets the value property to the total price of the order and the currency property to 'USD'.

<script>
    p2sq.push({
      et: 'InitiateCheckout', p: {
      content_ids: ['{{ product.id }}'],
      content_type: 'product',
      value: {{productPrice}},
      currency: 'USD',
    }});
</script>

Purchase Event

(checkout.liquid - thank-you.liquid)

In Shopify, the "Purchase" event is usually triggered in the checkout.liquid or thank_you.liquid file. However, access to the use of these files is only available to Shopify Plus customers.

You can use a Liquid and JavaScript code like below to trigger the "Purchase" event:

{% if first_time_accessed %}
  <script>
    p2sq.push({
      et: 'Purchase',
      p: {
        content_ids: [{% for line_item in checkout.line_items %}'{{line_item.product.id}}'{% unless forloop.last %}, {% endunless %}{% endfor %}],
        content_type: 'product',
        value: '{{ checkout.total_price | money_without_currency }}',
        currency: 'USD'
      },
      eid: '{{ checkout.order_id }}'
    });
  </script>
{% endif %}

This code sends a "Purchase" event to the Facebook Pixel, along with the total price of the order, the currency, the IDs of the items purchased. This event is triggered the first time a checkout page is accessed (when the variable first_time_accessed is true).

Therefore, the first_time_accessed statement usually ensures that a purchase event is only triggered the first time a user views the page. If the user reloads the page, first_time_accessed returns false and the "Purchase" event is not fired again.


OR Post Purchase Page

<script>
(function() {
  window.p2sq = window.p2sq || [];

  // make sure the initial conversion isn't tracked twice
  if (!Shopify.wasPostPurchasePageSeen) {
      var order = window.Shopify.order;

      p2sq.push({
          et: 'Purchase',
          p: {
              content_ids: order.lineItems.map(function (item) {
                  return {
                      id: Number(item.id).toString(),
                      quantity: item.quantity
                  };
              }),
              content_type: 'product',
              value: order.totalPrice,
              currency: 'SEK'
          },
          eid: Number(order.id).toString()
      });
  }

  // set up additional conversion tracking
  Shopify.on('CheckoutAmended', function(newOrder, previousOrder) {
    // identify which items were recently added, if any
    var oldItems = previousOrder.lineItems.map(function (line) { return line.id; });

    var addedItems = newOrder.lineItems.filter(
      function (line) { return oldItems.indexOf(line.id) < 0; }
    );
    // no new items were added, so we skip conversion tracking
    if (addedItems.length === 0) {
      return;
    }


    p2sq.push({
      et: 'Purchase',
      p: {
        content_ids: addedItems.map(function(item) {
            return {
              id: Number(item.id).toString(),
              quantity: item.quantity
            };
          }),
        content_type: 'product',
        value: order.totalPrice,
        currency: 'SEK'
      },
      eid: Number(order.id).toString()
    });
  });
})();
</script>

Consent management and data privacy

To stay compliant in regard to data protection, you should only activate script if users given consent within your Consent Management framework.

Contents

About SignalSight

SignalSight is an experienced tech solution who strives to connect brands with their customers like never before.

About SignalSight Server-side Signal Success Stories Pricing Docs Contact Us

Privacy Policy | Terms & Conditions