Webclat / Ecommerce
ecomm.webclat.com

How do I maintain session/cross-domain tracking continuity when Shopify checkout runs on myshopify.com or shop.app?

Cookies don't cross domain boundaries. When checkout lives on a different registrable domain than your storefront, GA4's session has to be carried across on purpose - it won't happen by default.

Quick answer

Where your Shopify plan supports it, move checkout onto the primary domain to remove the cross-domain problem entirely. Where checkout must stay on myshopify.com or shop.app, capture the GA4 client id and any ad-click id on the storefront before the shopper reaches checkout, pass them forward explicitly (for example via a query parameter your custom pixel reads), and send the purchase event using that explicit client id rather than relying on gtag.js's automatic, cookie-based identity on the checkout domain.

Why this happens

Cookies are scoped per registrable domain. myshopify.com and shop.app are entirely different registrable domains from a merchant's custom domain, so a first-party analytics cookie set while browsing the storefront is simply not visible to code running on checkout's domain. This is standard browser cookie-scoping behavior, not a Shopify-specific defect - any platform whose checkout is hosted cross-domain runs into the identical problem, and it's the same class of issue Universal Analytics' old cross-domain linker parameter existed to solve for other multi-domain setups.

Fix it

  1. Check whether "checkout on your domain" is available on your Shopify plan under Settings > Domains - Shopify has been consolidating checkout onto the primary domain for most plans, and enabling it removes the cross-domain cookie problem outright.
  2. If checkout must stay cross-domain, capture the GA4 client id (the _ga cookie value) and session id on the storefront side before the shopper reaches checkout.
  3. Pass that client id forward using a mechanism the checkout's custom pixel can actually read - since the pixel can't read the storefront's separate cookie jar, common approaches are encoding the id into the cart/checkout URL as a query parameter, or relying on Shopify's own customer/session identifiers to correlate the two sides after the fact.
  4. On the checkout_completed custom pixel, send the purchase event to GA4 via the Measurement Protocol directly (server-side, or as a fetch call from inside the pixel) using the explicit client id you captured - not gtag.js's automatically-generated one, which will simply be a fresh, unrelated id in the checkout's separate cookie context.
  5. Apply the same forwarding pattern to ad-platform click ids (gclid, fbclid): capture them on the storefront, pass them through to checkout, and attach them to the CAPI or server-side event rather than assuming a browser pixel on checkout has access to them.

Branch: if "checkout on your domain" is available on your plan but hasn't been enabled, do that first - it's a one-time settings change that eliminates every downstream workaround in this fix, rather than a partial mitigation.

How to verify it worked

Runtime check

With DevTools open, browse the storefront through to checkout on a real, cookies-allowed session (not incognito). In Application > Storage, note the _ga cookie's client id value while still on the storefront. Then, in the Network tab at checkout completion, filter for requests to google-analytics.com/g/collect or /mp/collect and inspect the cid parameter on the purchase hit. If the two values match, continuity worked. If the checkout-side hit shows a freshly generated client id instead, the session wasn't carried through, and GA4 will record that purchase as a brand-new, unattributed user rather than the same session that clicked the original ad.

Find out what your tracking actually reports.

A runtime audit of your store: every tag that fires, every event that reaches your analytics and ad platforms, and where the numbers diverge from the orders table. Evidence first, opinions second.

Request an audit