Docs · 02 of 07
Install on Shopify
Two pieces: the script on your storefront, and a custom pixel for checkout. Shopify does not let ordinary theme scripts run on the checkout, which is why purchases need their own path.
1. Point a subdomain at the tracker
Same as any other install: one A record on your store domain, pointing at the IP in your welcome email.
Type Name Value TTL
A metrics 203.0.113.42 300Add it wherever your store’s DNS lives. If the domain is managed by Shopify, that is Settings → Domains → your domain → DNS settings.
2. Add the script to your theme
In the admin: Online Store → Themes → Edit code, open layout/theme.liquid, and put the tag just before </head>.
<script
defer
src="https://metrics.example.com/script.js"
data-website-id="b6c9e2a1-4f3d-4a02-9f77-1c5b0d8e2a44"
></script>This covers the storefront: collections, products, cart, everything up to the point the customer leaves for checkout.
3. Add the checkout pixel
Checkout runs in Shopify’s own sandbox and theme code does not execute there. A custom pixel does, in a worker with a restricted API, which is exactly the isolation you want on a page handling payment.
Go to Settings → Customer events → Add custom pixel, name it Pear Metrics, and paste:
analytics.subscribe('checkout_completed', event => {
const checkout = event.data.checkout;
fetch('https://metrics.example.com/api/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
type: 'event',
payload: {
website: 'b6c9e2a1-4f3d-4a02-9f77-1c5b0d8e2a44',
hostname: 'example.com',
url: '/checkout/completed',
name: 'purchase',
data: {
// Money, and nothing that identifies the buyer.
value: checkout.totalPrice.amount,
currency: checkout.totalPrice.currencyCode,
items: checkout.lineItems.length,
},
},
}),
});
});Set the pixel’s permission to Not required for customer privacy, because it collects no personal data and gating it would silently drop the orders you are trying to count.
What not to put in that payload
The event.data.checkout object contains the customer’s email, shipping address and phone number. None of it belongs here. Sending it would put personal data into a database whose entire value is that it holds none, and it would make you a controller of data you did not need to collect.
Order value, currency and item count are enough to compute revenue, ROAS and CPA. The order ID is not needed either: this is a spend-versus-outcome table, not an order system.
4. Make the purchase count as a conversion
In the dashboard, go to Marketing → Settings → Conversion events and pick purchase from the observed event names.
Pick it from the list rather than typing it. An event name typed from memory that matches nothing produces a null CPA with no error anywhere, and it takes a surprisingly long time to notice.
5. Tag your ads
Shopify rewrites some URLs, so check that your UTMs survive to the landing page. In particular, a campaign pointing at a collection with existing query parameters needs the UTMs appended rather than replacing them.
UTM tagging for Google Ads and Meta has the templates.
Known Shopify quirks
- Shop Pay and accelerated checkouts skip the storefront cart, so the session that produced the order may have very few page views. That is fine: the session is still attributed on its landing UTMs.
- Post-purchase upsells fire
checkout_completedonce, for the original order. Upsell revenue is not counted unless you subscribe to that event too. - Theme app extensions that lazy-load the head can delay the script. If Realtime looks empty, check the tag is in
theme.liquidrather than injected by an app.