Key takeaways
- Shopify’s Customer Events API (Settings → Customer events → Add custom pixel) is the right place for custom event tracking.
- Standard Shopify events include page_viewed, product_viewed, product_added_to_cart, and checkout_completed.
- Custom pixels run in a sandboxed environment with access to all checkout events - something theme.liquid scripts can’t do.
- You write standard JavaScript inside the custom pixel editor - no Shopify-specific syntax required.
Custom event tracking tells you what shoppers actually do on your store — not just which pages they visit, but when they add products to their cart, start checkout, or reach your thank-you page. Shopify’s Customer Events API makes this trackable without digging into theme code.
How do I add events in Shopify?
Go to Settings → Customer events → Add custom pixel. This opens a JavaScript editor where you write code that listens to Shopify’s standard events and fires your own tracking code in response.
Shopify’s standard events
Shopify exposes a set of standard events across the shopping journey. Your custom pixel can listen to any of them:
Page events:
page_viewed— fires on every page load
Product events:
product_viewed— fires when a product page is viewedproduct_added_to_cart— fires when an item is added to the cartsearch_submitted— fires when a search query is submitted
Checkout events:
checkout_started— fires when checkout beginscheckout_address_info_submitted— fires when address is enteredcheckout_shipping_info_submitted— fires when shipping method is selectedpayment_info_submitted— fires when payment info is enteredcheckout_completed— fires on the order confirmation pageorder_created— fires when an order is successfully placed
These events come with contextual data — the product that was viewed, the cart value at checkout start, the order total at completion.
Related: Modify checkout.liquid in Shopify Plus.
Writing a custom pixel
Here’s a basic example that sends a GA4 event when a product is added to cart:
analytics.subscribe('product_added_to_cart', (event) => {
const cartLine = event.data.cartLine;
// Send to GA4 via dataLayer (if GTM is installed)
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'add_to_cart',
ecommerce: {
currency: cartLine.merchandise.product.vendor,
items: [{
item_id: cartLine.merchandise.sku,
item_name: cartLine.merchandise.product.title,
price: cartLine.cost.totalAmount.amount,
quantity: cartLine.quantity
}]
}
});
});
And for a Meta Pixel purchase event on checkout completion:
Related: Add Google Tag Manager to Shopify.
Related: Add Custom JavaScript in Shopify.
analytics.subscribe('checkout_completed', (event) => {
const order = event.data.checkout;
fbq('track', 'Purchase', {
value: order.totalPrice.amount,
currency: order.currencyCode,
content_ids: order.lineItems.map(item => item.variant.sku),
content_type: 'product'
});
});
Important: The analytics.subscribe() function is provided by Shopify’s sandbox environment. You don’t need to import it — it’s available automatically in all custom pixels.
Setting up a custom pixel step by step
Step 1 - Go to Settings → Customer events
Step 2 - Click Add custom pixel
Step 3 - Give it a name (e.g., “GA4 Custom Events” or “Meta Purchase Event”)
Step 4 - In the Code section, write your JavaScript using analytics.subscribe()
Step 5 - Set the Customer privacy permission level:
- Not required — fires for all visitors regardless of consent
- Preferences — requires analytics consent
- Analytics — requires analytics consent
- Marketing — requires marketing consent
For purchase tracking, select “Marketing” if you’re sending to ad platforms, or “Analytics” for GA4.
To measure results, see add tracking scripts to shopify.
Step 6 - Click Save then Connect
Testing your custom pixel
Shopify’s built-in debugger. In the Customer Events editor, there’s a live event feed that shows events firing in real time. Open your storefront in another tab and browse around — you should see page_viewed events appear immediately.
Browser console. Because custom pixels run in a sandboxed iframe, you can’t see their console.log output directly. Use Shopify’s debugger panel instead.
GA4 DebugView. In your GA4 property, go to Configure → DebugView. Trigger events on your storefront and watch them appear in real time.
Custom events vs. standard app integrations
Shopify has pre-built integrations for Google Analytics, Google Ads, Meta, TikTok, Snapchat, and others in the Customer events section. These handle standard purchase tracking automatically.
Use custom pixels when:
- You need to track events the standard integration doesn’t cover (e.g., specific button clicks, scroll depth, custom funnel steps)
- You need to send events to a less common analytics platform
- You want to send additional custom data with standard events (e.g., customer lifetime value, product category)
For most stores, the standard integrations cover 80% of needs. Custom pixels fill the gaps.
FAQ
Inside a sandboxed iframe injected by Shopify - which is why you can't reach into window or the page DOM directly. The benefit is reliability: pixels keep firing on the checkout pages where merchants traditionally lose visibility, and they can't be broken by theme updates.
No. Custom pixels run in a sandboxed environment with limited globals - vanilla JavaScript only. If you need a library, either include it via a CDN inside the pixel code, or build the integration without one. Most tracking can be done with fetch and standard browser APIs.
Yes. The Customer Events API is available on all Shopify plans, including Basic. This is significant because pre-2023, server-side checkout tracking was largely Shopify Plus only. Custom pixels open up checkout-event tracking to every plan.
Push to dataLayer from inside the pixel - but because the pixel runs in a sandbox, you need to push to the parent window's dataLayer using parent.window.dataLayer.push(). Most stores skip this and use Shopify's native GTM connector instead, then add a custom pixel only for events the connector doesn't cover.
Two common causes: (1) the customer privacy permission is set higher than the visitor's consent (e.g., "Marketing" required but the visitor declined marketing), or (2) the pixel is subscribed to the wrong event - checkout_completed fires on the thank-you page, not order_created (which fires server-side and isn't always emitted to client pixels).