Shopify
Step-by-step guide to add OnyxMetric cookieless analytics to your Shopify store and start tracking visitors
On Shopify the tag goes into your theme's theme.liquid layout, which wraps every storefront page. Checkout runs on Shopify's own sandboxed pages, so purchases are tracked separately with a custom web pixel.
Copy your tracking snippet
In OnyxMetric, open your site's Site Settings and copy the tracking script. It looks like this:
<script src="https://app.onyxmetric.com/api/script.js?siteId=YOUR_SITE_ID" async></script>YOUR_SITE_ID is the numeric ID of your site.
Add the snippet to Shopify
- In Shopify admin, go to Online Store > Themes.
- On your current theme, click the ... button next to Customize and choose Edit code.
- Open
theme.liquidin the Layout folder. - Paste the snippet just before the closing
</head>tag and click Save.
Theme updates can overwrite theme.liquid. Shopify has no child themes, so after updating a purchased theme, add the snippet again.
Check that it works
Load your live site and click through a few pages. Pageviews show up in the OnyxMetric dashboard within seconds.
If nothing arrives:
- View the page source and search for
script.js?siteId=to confirm the tag is present. - In the browser's Network tab, check that
script.jsreturns200and that requests go to/api/track. - Turn off ad blockers, or proxy the script through your own domain.
- Read script troubleshooting for other causes.
Track custom events
Storefront templates can call window.onyx.event() directly. Wrap the calls in a DOMContentLoaded listener, and divide Liquid prices by 100 because they are in cents.
Back up your theme before editing code. Liquid object names such as product.selected_or_first_available_variant and the form selectors below vary between themes, so adjust them to match yours.
View product
Add this to your main product template (sections/main-product.liquid or templates/product.liquid):
<script>
document.addEventListener('DOMContentLoaded', function () {
var variant = {{ product.selected_or_first_available_variant | json }};
window.onyx.event('view_item', {
item_id: variant.sku || variant.id,
item_name: {{ product.title | json }},
item_variant: variant.title === 'Default Title' ? null : variant.title,
price: variant.price / 100,
currency: {{ cart.currency.iso_code | json }}
});
});
</script>Add to cart
In the same template, listen on the product form. Themes with an AJAX cart drawer usually fire their own event after an item is added, and hooking that is more reliable than the form submit.
<script>
document.addEventListener('DOMContentLoaded', function () {
var form = document.querySelector('form[action="/cart/add"]');
if (!form) return;
form.addEventListener('submit', function () {
var variant = {{ product.selected_or_first_available_variant | json }};
var qty = form.querySelector('[name="quantity"]');
window.onyx.event('add_to_cart', {
item_id: variant.sku || variant.id,
item_name: {{ product.title | json }},
price: variant.price / 100,
currency: {{ cart.currency.iso_code | json }},
quantity: qty && parseInt(qty.value, 10) > 0 ? parseInt(qty.value, 10) : 1
});
});
});
</script>Begin checkout
Add this to your cart template (sections/main-cart-items.liquid or templates/cart.liquid):
<script>
document.addEventListener('DOMContentLoaded', function () {
var button = document.querySelector('[name="checkout"]');
if (!button) return;
button.addEventListener('click', function () {
var cart = {{ cart | json }};
window.onyx.event('begin_checkout', {
currency: cart.currency,
value: cart.total_price / 100,
items: cart.items.map(function (item) {
return { item_id: item.sku || item.variant_id, quantity: item.quantity, price: item.final_price / 100 };
})
});
});
});
</script>Event properties are capped at 2048 characters of serialized JSON, and larger payloads are rejected rather than truncated. Keep items compact, or send only totals for big carts.
Purchase
Checkout and the order status page do not load your theme. The old Order status page > Additional scripts field is deprecated, so track purchases with a custom web pixel instead. Pixels run in a sandbox with no access to window.onyx, so the pixel posts the event straight to OnyxMetric's track endpoint.
- In Shopify admin, go to Settings > Customer events.
- Click Add custom pixel, name it
OnyxMetric, and click Add pixel. - Paste the code below, replace
YOUR_SITE_ID, then Save and Connect the pixel.
analytics.subscribe("checkout_completed", (event) => {
const checkout = event.data.checkout;
const items = (checkout.lineItems || []).map((li) => ({
id: li.variant?.sku || li.variant?.id,
qty: li.quantity,
price: li.variant?.price?.amount,
}));
fetch("https://app.onyxmetric.com/api/track", {
method: "POST",
headers: { "Content-Type": "application/json" },
keepalive: true,
body: JSON.stringify({
type: "custom_event",
site_id: "YOUR_SITE_ID",
event_name: "purchase",
// properties must be a JSON string of at most 2048 characters
properties: JSON.stringify({
transaction_id: checkout.order?.id || checkout.token,
value: checkout.totalPrice?.amount,
currency: checkout.currencyCode,
items,
}),
}),
});
});checkout_completed fires once per placed order. The same Customer Events API also exposes product_added_to_cart and checkout_started, so you can move add-to-cart and begin-checkout into the pixel if you prefer.
Next steps
- Track custom events such as signups, purchases, and clicks.
- Identify users to tie sessions to accounts.
- Proxy the script through your own domain to get past ad blockers.
- Script attributes let you skip or mask URLs and tag events.