Shopify

Last updated:

|Edit this page

Setting up a custom web pixel

The simplest way to add PostHog to Shopify is using a custom web pixel. To set this up, first, go to the customer events tab in your store settings, click "Add custom pixel," and give your pixel a name.

Next, add code that contains:

  1. The customer events you want to subscribe to. You can find a complete list in Shopify's Web Pixels API documentation.

  2. Your PostHog JavaScript snippet which you can get from your project settings.

  3. The rest of your PostHog capture logic.

As an example, here is the code for subscribing to a checkout_completed event. Every time a user checks out, we capture an event. We also call posthog.identify() so that we can track the user across different sessions:

JavaScript
<<<<<<< Updated upstream
analytics.subscribe('checkout_completed', (event) => {
!(function (t, e) {
var o, n, p, r
e.__SV ||
((window.posthog = e),
(e._i = []),
(e.init = function (i, s, a) {
function g(t, e) {
var o = e.split('.')
2 == o.length && ((t = t[o[0]]), (e = o[1])),
(t[e] = function () {
t.push([e].concat(Array.prototype.slice.call(arguments, 0)))
})
}
;((p = t.createElement('script')).type = 'text/javascript'),
(p.async = !0),
(p.src = s.api_host + '/static/array.js'),
(r = t.getElementsByTagName('script')[0]).parentNode.insertBefore(p, r)
var u = e
for (
void 0 !== a ? (u = e[a] = []) : (a = 'posthog'),
u.people = u.people || [],
u.toString = function (t) {
var e = 'posthog'
return 'posthog' !== a && (e += '.' + a), t || (e += ' (stub)'), e
},
u.people.toString = function () {
return u.toString(1) + '.people (stub)'
},
o =
'capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId'.split(
' '
),
n = 0;
n < o.length;
n++
)
g(u, o[n])
e._i.push([i, s, a])
}),
(e.__SV = 1))
})(document, window.posthog || [])
posthog.init('<ph_project_api_key>', { api_host: 'https://us.i.posthog.com' })
const checkout = event.data.checkout
=======
analytics.subscribe("checkout_completed", (event) => {
!function(t,e){var o,n,p,r;e.__SV||(window.posthog=e,e._i=[],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t[o[0]],e=o[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.async=!0,p.src=s.api_host+"/static/array.js",(r=t.getElementsByTagName("script")[0]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e[a]=[]:a="posthog",u.people=u.people||[],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="capture identify alias people.set people.set_once set_config register register_once unregister opt_out_capturing has_opted_out_capturing opt_in_capturing reset isFeatureEnabled onFeatureFlags getFeatureFlag getFeatureFlagPayload reloadFeatureFlags group updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures getActiveMatchingSurveys getSurveys getNextSurveyStep onSessionId".split(" "),n=0;n<o.length;n++)g(u,o[n]);e._i.push([i,s,a])},e.__SV=1)}(document,window.posthog||[]);
posthog.init('<ph_project_api_key>',{api_host:'<ph_client_api_host>'})
const checkout = event.data.checkout;
>>>>>>> Stashed changes
posthog.identify(checkout.email, {
email: checkout.email,
first_name: checkout.billingAddress.firstName,
last_name: checkout.billingAddress.lastName,
})
posthog.capture('merch store order submitted', {
value: checkout.totalPrice.amount,
created_at: event.timestamp,
order_number: checkout.order.id,
userId: event.clientId,
order_id: checkout.order.id,
products: checkout.lineItems.map((item) => {
return {
product_id: item.id,
title: item.variant.product.title,
quantity: item.quantity,
price: item.variant.price.amount,
currency: item.variant.price.currencyCode,
sku: item.variant.sku,
size: item.variant.product.size,
}
}),
})
})

In the above code, we capture the event with details like userID, order_number, product_id, price, and more. This is then viewable in PostHog:

Shopify events in PostHog

Installing PostHog in a Shopify theme

To have unrestricted access to the features of PostHog in your Shopify store, you can install PostHog in your Shopify theme. To do this:

  1. Get your PostHog JavaScript snippet from your project settings
  2. Login to your Shopify dashboard
  3. Go to 'Online Store' -> 'Themes' (see image below)
  4. On your theme, click 'Actions' -> 'Edit code' (see image below)

Shopify Dashboard

  1. You should now be seeing a code editor. Click on theme.liquid under 'Layout' on the left sidebar (see image below)
  2. Navigate until you see the closing </head> tag. Paste your snippet there, before that tag, like in the image below:

Shopify Snippet

  1. Click the green save button on the top right and you're good to go - PostHog should now capturing events on your Shopify store!

To confirm PostHog is configured correctly, visit your store and then check if the events from your session appear in the PostHog activity tab. This may take a few minutes.

Advanced tracking

This section requires some knowledge of HTML and Shopify's Liquid templating engine.

It can be useful to track additional events on your Shopify store, such as when a user adds an item to their cart or completes a purchase.

Although autocapture does capture these events, you may need to add additional metadata. This information can be used in further analysis in aggregate or when understanding behavior of an individual user.

Add data attributes to buttons

To track which product a user adds to their cart, we can use a data-ph-capture-attribute on the 'Add to cart' button (generally in product.liquid in Shopify). While this still requires adding code, it's less involved than creating a custom event. For example, capturing the product title and price (divided by 100) looks like this:

HTML
<input
type="submit"
class="add-to-cart-button"
value="{{ 'products.product.add_to_cart' | t }}"
data-ph-capture-attribute-product-name="{{product.title}}"
data-ph-capture-attribute-product-price="{{product.price | divided_by: 100 }}"
/>

Once set up, the Add to cart button autocapture event in PostHog will include the properties for each of the attributes prefixed with data-ph-capture-attribute- and their values.

Data attributes in an autocaptured event

Use custom events and properties

This requires a Shopify Plus account because you'll need to modify your store's checkout settings. This option is available in the Shopify admin by navigating to SettingsCheckoutOrder status pageAdditional scripts.

If you want to capture orders more accurately, you can do so using a custom event. These enable you to add properties for any of the fields in your order including price, order number, size, and currency.

To add a custom event to your Shopify checkout page, add a script like this to your checkout settings:

This code should be used as a guide and may need to be modified depending on the setup of your store.

HTML
{% if first_time_accessed %}
<script>
posthog.capture('order_submitted', {
value: '{{ order.total_price }}',
created_at: '{{ order.created_at }}',
order_number: '{{ order.order_number }}',
userId: '{{ customer.id }}',
order_id: '{{ checkout.order_id }}',
"products": [{% for line_item in line_items %}{
"product_id": '{{ line_item.product.type }}',
"color_id": '{{ line_item.variant.option1 }}',
"size": '{{ line_item.variant.option2 }}',
"quantity": {{ line_item.quantity }},
"price": {{ line_item.final_price| divided_by: 100.0 }},
"currency": '{{ checkout.currency }}',
"sku": '{{ line_item.product_id }}_{{ line_item.variant_id }}',
}{% unless forloop.last %}, {% endunless %}{% endfor %}]
});
</script>
{% endif %}

Tip: Be sure to wrap the code in {% if first_time_accessed %} to ensure the event is only sent once.

Once setup, you can see the order's total price including taxes (value) and the array of products that were ordered with specific info about the variants in PostHog:

Order details sent from Shopify as properties on a custom event

What can you do with this data?

You can use this data to answer questions like:

  • Which products are being left in the cart most often?
  • Which products are being purchased together most often?
  • Which marketing campaigns are driving sales of different products?
  • How does regionality of shoppers affect the products they buy?

Questions?

Was this page useful?

Next article

Svelte

PostHog makes it easy to get data about traffic and usage of your Svelte app. Integrating PostHog into your site enables analytics about user behavior, custom events capture, session recordings, feature flags, and more. This guide walks you through integrating PostHog into your SvelteKit app using the JavaScript Web and Node.js SDKs. Client-side setup Install posthog-js using your package manager: Then, if you haven't created a root layout already, create a new file called +layout.js…

Read next article