Pixel tracking on the post-purchase page

If your store has installed an app that adds a post-purchase page to your store's checkout, then any custom pixel tracking that you use on your store might not capture certain tracking events. Custom tracking pixels that are added to your store's Additional scripts box track events on only the order status page, which comes after the post-purchase page in the checkout. If a customer leaves your store on the post-purchase page, then no events on the order status page are tracked.

To ensure that you capture conversion events properly, you can add a script that tracks events on the post-purchase page. This script can also track additional purchases that are made from the post-purchase page, such as upsells. After you add a post-purchase page script, you need to adjust your order status page script to ignore events that are already captured by the post-purchase page script.

You need to change how your store tracks events only if you use a custom tracking pixel. For example, if you set up Google Analytics through Online Store > Preferences, then it already captures events correctly on your post-purchase page.

Considerations

The post-purchase page additional script is similar to the order status page additional scripts, but with a few key differences:

  • The script is added to the post-purchase page, not the order status page.
  • The field allows only JavaScript. Liquid code isn't accepted.
  • The only HTML tag allowed is <script>.
  • The script runs within a sandbox and isn't included on the main page.
  • You can add a post-purchase page script only if your store has installed an app that adds a post-purchase page to your checkout.

Running the script within a sandbox ensures that the script is secure and is used for its intended purpose.

Shopify Support can’t help with post-purchase page scripts. If you need assistance, then you can post in the Shopify Community or hire a Shopify Partner.

Compatibility with scripts on the order status page

To ensure that your pixels correctly track all conversion events, set up tracking scripts on both the post-purchase page and the order status page. To avoid counting conversion events twice, you can use the post_purchase_page_accessed Liquid variable in scripts that run on the order status page.

If a customer lands on the post-purchase page and then navigates to the order status page, then the post_purchase_page_accessed variable returns true. If a customer doesn't arrive at the post-purchase page, then the variable returns false.

For example, you can use the following format for your scripts on the order status page:

{% if first_time_accessed == true and post_purchase_page_accessed == false %}
<script>
   // insert your tracking script
</script>
{% endif %}

Available APIs

You can use JavaScript globals to give tracking scripts access to the data that they need. The accessible data is available under window.Shopify.

Tracking purchases made on the post-purchase page

To track additional purchases that are made through the post-purchase page, you can subscribe to the Shopify.on event.

After you subscribe, the following actions occur whenever a post-purchase changeset is successfully applied:

  • Your handler is called with two Order-type arguments: order and outdated order.
  • The globals under window.Shopify are updated so that the scripts can use the updated data.

Handlers subscribed to this event can have as little as 500 ms to execute. Make sure to load any dependencies that you need ahead of time.

Add the post-purchase page script

Before you add the post-purchase page script, for the post-purchase field to display in your Shopify Admin, make sure that you set up either the Google and YouTube channel or download a third party post-purchase app.

Steps:

  1. From your Shopify admin, go to Settings > Checkout.
  2. In the Post-purchase additional scripts field, enter your script.
  3. Click Save.

Example script

You can use the following basic script template to help you build your own post-purchase page script. This example script uses Google Analytics to track the initial conversion, and explains how to track additional purchases. This example is very simple and your final script will likely differ from it.

Example script files

Example script for the order status page:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-FYNQ742HTX"></script>
<script>
(function() {
  // make sure the initial conversion isn't tracked twice
  {% if first_time_accessed == false or post_purchase_page_accessed == true %}
    return;
  {% endif %}
  // set up google analytics
  window.dataLayer = window.dataLayer || [];
  function gtag() {
    dataLayer.push(arguments);
  }
  gtag('js', new Date());
  gtag('config', 'G-FYNQ742HTX');
  // track initial conversion
  var order = window.Shopify.order;

  gtag('event', 'purchase', {
    affiliation: 'My Shopify Store',
    transaction_id: Number(order.id).toString(),
    value: order.totalPrice,
    currency: order.currency,
    items: order.lineItems.map((item) => ({
      id: Number(item.id).toString(),
      name: item.title,
      category: item.product.type,
      price: item.price,
      quantity: item.quantity,
      variant: Number(item.variant.sku).toString(),
    })),
  });
})();
</script>

Example script for the post-purchase page:

<script async src="https://www.googletagmanager.com/gtag/js?id=G-FYNQ742HTX"></script>
<script>
(function() {
  // set up google analytics
  window.dataLayer = window.dataLayer || [];

  function gtag() {
    dataLayer.push(arguments);
  }

  gtag('js', new Date());
  gtag('config', 'G-FYNQ742HTX');

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

    // track initial conversion
    gtag('event', 'purchase', {
      affiliation: 'My Shopify Store',
      transaction_id: Number(order.id).toString(),
      value: order.totalPrice,
      currency: order.currency,
      items: order.lineItems.map(function(item) {
        return {
          id: Number(item.id).toString(),
          name: item.title,
          category: item.product.type,
          price: item.price,
          quantity: item.quantity,
          variant: Number(item.variant.sku).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;
    }

    // track additional purchase
    gtag('event', 'purchase', {
      affiliation: 'My Shopify Store',
      transaction_id: Number(order.id).toString(),
      value: order.totalPrice,
      currency: order.currency,
      items: addedItems.map(function (item) {
        return {
          id: Number(item.id).toString(),
          name: item.title,
          category: item.product.type,
          price: item.price,
          quantity: item.quantity,
          variant: Number(item.variant.sku).toString(),
        };
      }),
    });
  });
})();
</script>

References

The following table contains the type definitions for the attributes that are exposed to post-purchase additional scripts through window.Shopify:

FieldDefinition
window.Shopify
shopThe details of the shop from where the order was placed.
orderThe details of the order.
pageUrlThe current page's URL.
wasPostPurchasePageSeenWhether the customer viewed the post-purchase page during this checkout. It will be false when rendering for the first time, and true otherwise, such as if the page is reloaded.
on(event: string, handler: function): voidSubscribes to an event. Currently, only the CheckoutAmended event is supported.
off(event: string, handler: function): voidUnsubscribes handler from the given event. Currently, only the CheckoutAmended event is supported.
Shop
idThe ID of the shop.
currencyThe store's currency in ISO 4217 format. For example, USD. For more details, refer to shop.currency.
Order
idThe order's internal identifier.
numberThe integer representation of the order name. For example, 1025.
checkoutTokenThe checkout's internal identifier.
customerThe customer associated with the order.
lineItemThe line items for the order.
subtotalPriceThe subtotal price of all the items in the order after both line-item and cart discounts have been applied. The subtotal doesn't include taxes (unless taxes are included in the prices), shipping costs, or tips.
totalPriceThe total price of the order.
currencyThe ISO 4217 code of the order's currency.
discountsThe sum of the amount of the discounts applied to the order.
Customer
idThe ID of the customer.
emailThe email address of the customer.
acceptsMarketingWhether the customer had accepted marketing. It will be true if the customer accepts marketing, and false if not.
hasAccountWhether the customer email is associated with a customer account. It will be true if the email is listed on a customer account, and false if not. For more details, refer to customer.has_account.
firstNameThe first name of the customer.
lastNameThe last name of the customer.
ordersCountThe total number of orders that the customer has placed.
totalSpentThe total amount that the customer has spent on all orders.
LineItem
finalLinePriceThe combined price of all the items in the line item. This is equal to line_item.final_price multiplied by line_item.quantity.
finalPriceThe price of the line item, including all line-level discount amounts.
lineLevelTotalDiscountThe total amount of all discounts applied to the line item specifically. This doesn't include discounts that are added to the cart.
optionsWithValuesAn array of selected values from the item's product options. For more details, refer to line_item.options_with_values.
originalLinePriceThe combined price of the quantity of items included in the line, before discounts were applied. This is equal to line_item.original_price multiplied by line_item.quantity.
originalPriceThe original price of the line item before discounts were applied.
priceThe unit price of the line item. The price reflects any discounts that are applied to the line item. Available only to stores located in Germany or France.
productThe product of the line item.
propertiesAn array of custom information for an item that has been added to the cart. For more information, refer to line_item.properties.
quantityThe quantity of the line item.
titleThe title of the line item. For more information, refer to line_item.title.
variantThe variant of the line item.
Product
idThe ID of the product.
typeThe type of the product.
ProductVariant
idThe ID of the variant.
skuThe SKU of the variant.
CartDiscount
idThe discount application's internal identifier.
codeThe code of the discount, if it has one.
typeThe type of the discount. Possible values are: automatic, discount_code, manual, and script.
amountThe total amount that the price of the order is reduced by the discount.
Ready to start selling with Shopify?Try it free