By Dylan HuntJune 5th, 2026shopifypixelscustomer-events

Migrating Shopify Tracking to Customer Events (Web Pixels): a Practical Guide

If your conversion tracking still lives in ScriptTags or a theme.liquid snippet, you have a measurement gap right now. The new Shopify checkout never ran that code, so everything from "began checkout" onward is invisible to it. Customer events are Shopify's replacement: one event stream, available on every plan, that works across the storefront and the checkout.

This guide migrates a typical setup in four steps, with code you can paste. (Just need the basics? Adding a custom pixel without an app is the five-minute version, and the event payload reference covers every funnel event in depth.)

How customer events actually work

Shopify publishes a stream of standard events to web pixels: small JavaScript subscribers that run in a sandboxed worker. The stream covers the whole funnel, from page_viewed and product_viewed through product_added_to_cart, checkout_started, and checkout_completed. The full list is in Shopify's standard events reference.

There are two kinds of pixel:

  • Custom pixels are pasted into Settings → Customer events → Add custom pixel in the admin. No app, no theme edit. Most merchant tracking belongs here.
  • App pixels ship with apps through the Web Pixels API and are present once the app is installed. The Meta, Google, and TikTok channel apps all register one, so check whether your channel app already migrated before writing anything yourself.

The sandbox is the part that surprises people. A pixel cannot touch the DOM, read cookies on your domain directly, or load arbitrary scripts the way a theme snippet could. In exchange, it receives clean, structured payloads and runs on checkout pages where your theme code never could.

Step 1: Inventory what you have

Before writing the new pixel, list every tracker you run today and where it lives:

  1. Theme code. Search your theme for gtag(, fbq(, ttq., and dataLayer.push (Online Store → Edit code, then the search box).
  2. ScriptTags installed by apps. The fastest check is the storefront itself: view source and look for /script_tags/, or filter the network tab by your tracker domains.
  3. The old "Additional scripts" box, if your store is old enough to have used order-status-page scripts.

For each one, write down which events it actually cared about. Almost everything reduces to page views, product views, add to cart, begin checkout, and purchase.

Step 2: Create the custom pixel

Settings → Customer events → Add custom pixel, name it after the destination, and you get a code editor. The entire API surface you need is analytics.subscribe:

analytics.subscribe("page_viewed", (event) => {
  console.log("page viewed:", event.context.document.location.href);
});

analytics.subscribe("product_added_to_cart", (event) => {
  const line = event.data.cartLine;
  console.log("added:", line.merchandise.product.title, line.quantity);
});

analytics.subscribe("checkout_completed", (event) => {
  const checkout = event.data.checkout;
  console.log("purchase:", checkout.order?.id, checkout.totalPrice.amount);
});

Save, set the pixel's privacy permissions honestly, and click Connect. It's now live on the storefront and the checkout.

Step 3: Wire the payloads to your tracker

The sandbox can load tracker SDKs and can always fetch to a measurement endpoint. Here's GA4, end to end:

const GA_ID = "G-XXXXXXX";

// gtag.js works inside the pixel sandbox: load it, then translate
// Shopify's payloads into GA4 ecommerce events.
const script = document.createElement("script");
script.src = `https://www.googletagmanager.com/gtag/js?id=${GA_ID}`;
document.head.appendChild(script);

window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", GA_ID, { send_page_view: false });

analytics.subscribe("page_viewed", (event) => {
  gtag("event", "page_view", {
    page_location: event.context.document.location.href,
    page_title: event.context.document.title,
  });
});

analytics.subscribe("product_added_to_cart", (event) => {
  const line = event.data.cartLine;
  gtag("event", "add_to_cart", {
    currency: line.cost.totalAmount.currencyCode,
    value: Number(line.cost.totalAmount.amount),
    items: [{
      item_id: line.merchandise.product.id,
      item_name: line.merchandise.product.title,
      quantity: line.quantity,
    }],
  });
});

analytics.subscribe("checkout_completed", (event) => {
  const checkout = event.data.checkout;
  gtag("event", "purchase", {
    transaction_id: checkout.order?.id,
    currency: checkout.currencyCode,
    value: Number(checkout.totalPrice.amount),
    items: checkout.lineItems.map((item) => ({
      item_id: item.variant?.product?.id,
      item_name: item.title,
      quantity: item.quantity,
      price: Number(item.variant?.price?.amount ?? 0),
    })),
  });
});

The document available here belongs to the sandbox, which is why SDK loading works while reading your storefront's DOM doesn't.

One honest warning: don't double-fire. If the official Google or Meta channel app is installed and already sending these events through its app pixel, your custom pixel duplicates every conversion. Pick one path per destination.

Step 4: Verify, then delete the old code

Test with a real order on a development store, or a refunded test order:

  1. Open Settings → Customer events, confirm the pixel shows as connected, and watch your tracker's debug view (GA4 DebugView, Meta Events Manager test events).
  2. Confirm checkout_completed arrives with the right order total. This is the event your old setup was missing entirely.
  3. Only after the new numbers match reality, remove the theme snippets and ask app vendors about leftover ScriptTags. Running both "temporarily" is how stores end up with doubled conversion counts for a year.

Where this intersects with AI agents

Customer events are also how you'll measure the next traffic shift: agentic checkouts. The same checkout_completed payload fires whether a human or an AI shopping assistant completed the purchase. And if you want to see how often AI agents are reading your store before that purchase happens, that's exactly what AgentReady measures from the other side.

Questions about a migration that doesn't fit this shape? Multi-pixel setups, server-side tagging, headless storefronts: get in touch. This is what we do.

Make your store agent-ready

Get found and recommended by AI shopping assistants.

AgentReady adds Schema.org structured data, an llms.txt directory, and an AI-readability audit to your Shopify store, so ChatGPT, Perplexity, and Google can understand and recommend your products. Free for stores under 500 products.

Comments

Every comment here comes from a verified email. Write yours, confirm from your inbox, and it's live.

Loading comments…

Leave a comment

ShareXLinkedInFacebook

Written by Dylan Hunt, Founder, Caffeine and Commerce. We build Shopify stores that rank and that AI agents can read. Have a project? Get in touch.