Shopify Conversion Tracking with GA4 and GTM
Tracking Shopify conversions in GA4 through GTM. Customer events, Checkout Extensibility, Web Pixels API, server-side relay, and the gotchas the official docs gloss over.
Why Shopify tracking is harder than it should be
Shopify is a closed checkout. Until 2022, brands could inject custom JavaScript into the checkout pages and run GTM there. That changed with Checkout Extensibility, which moved checkout to a sandbox you cannot directly inject into. The result: most Shopify tracking guides written before 2023 are wrong. Most plug-and-play setups produce broken purchase tracking, no add-to-cart context, and bad data flowing into Meta and Google.
This guide walks the current state. As of 2026, there are three modern paths for Shopify + GA4 + GTM. Each has trade-offs.
Path 1: Customer Events with Shopify's Web Pixel API
Shopify's official path. Customer Events are predefined events Shopify emits (page_viewed, product_viewed, cart_viewed, checkout_started, checkout_completed) and you subscribe to them with a Custom Pixel inside the Shopify admin.
- Shopify Admin → Settings → Customer events → Add custom pixel.
- Write JavaScript that subscribes to events and forwards them. The pixel runs in a Shopify-managed iframe sandbox. You have limited DOM access; you do have access to
analytics.subscribe('event_name', callback). - Forward events to GTM via window.dataLayer. Inside the pixel, push events into a dataLayer that your GTM container reads. Or, equivalently, fire requests directly to GA4 Measurement Protocol from the pixel.
- Set up GA4 events that match Google's ecommerce schema. view_item, add_to_cart, begin_checkout, purchase, with item arrays.
Trade-offs. The pixel sandbox limits what you can do (no direct DOM manipulation, restricted network calls). Some events fire later than expected. The pixel is reliable but the schema mapping from Shopify event names to GA4 event names is the work nobody warns you about.
Path 2: GTM Web Pixel (community-built)
Several third parties have built community GTM extensions that handle the Shopify-to-GTM forwarding. Examples: Analyzify, TagBuilder, Littledata. These install via Shopify app or theme code and ship a dataLayer that mimics what you'd get on a non-Shopify store.
- Analyzify ($79+/month): Shopify-specific, full ecommerce schema, GTM-integrated. Handles checkout and thank-you-page tracking via a server-side relay.
- Littledata ($55+/month): Server-side ETL into GA4 with high accuracy claims. Strong on subscription analytics.
- TagBuilder ($49+/month): Lighter, code-first option.
- Elevar ($50+/month): The most-used in serious DTC stacks. Covers Meta CAPI, Google Enhanced Conversions, and GA4 with a full server-side relay. See Elevar and alternatives.
Path 3: DIY with theme code + GTM server container
The most engineering-heavy option. Install the GTM snippet in your theme. Use Shopify's standard liquid templates to push dataLayer events on product, collection, and cart pages. Use a Customer Events pixel for the checkout side because theme code doesn't run inside checkout.
Add a GTM server container (Stape or Google Cloud Run) and route everything through it. The server container fires Meta CAPI, Google Enhanced Conversions, GA4 via Measurement Protocol, TikTok Events API. You own the schema. You own the deduplication. You own everything that breaks.
This is the path most senior in-house teams pick because they want control and have engineering to support it. It's not a path you should pick because you don't want to pay for Elevar — the time investment is significant.
The events that matter on Shopify
| Shopify event | GA4 event | Notes |
|---|---|---|
| page_viewed | page_view | Fires automatically with the Google tag |
| product_viewed | view_item | Map item details from product context |
| collection_viewed | view_item_list | Pass collection ID as item_list_id |
| product_added_to_cart | add_to_cart | Pass cart line variant data |
| checkout_started | begin_checkout | Fires once per checkout initiation |
| checkout_shipping_info_submitted | add_shipping_info | Useful funnel step |
| checkout_completed | purchase | Pass transaction_id (order ID), value, currency, items |
| search_submitted | search | Pass search_term |
Common Shopify tracking failure modes
Purchase tracking only on /thank-you
Old setups expected thank-you-page JavaScript to fire on order confirmation. Checkout Extensibility broke that. If your purchase event only fires on the thank-you-page URL with custom JavaScript, you have lost most of your data. Migrate to Customer Events or a tracking app.
Double-counting from Pixel + CAPI + Shopify integration
The Shopify Facebook & Instagram channel sends purchases via CAPI. If you also fire the Pixel and send your own CAPI events without deduplication, Meta counts the conversion three times. Pick one CAPI source per pixel and disable the others, or use event_id deduplication everywhere.
Wrong item details
GA4 ecommerce expects item_id, item_name, price, quantity, item_category. Many Shopify integrations pass variant IDs as item_id but product titles as item_name, breaking joins. Be consistent across all events for the same item.
Currency code missing
GA4 requires the currency parameter on every ecommerce event. Without it, the event is logged but the revenue does not show up in reports. Always include "currency": "USD" (or whatever applies).
Subscription tracking
Shopify subscriptions (via Recharge, Bold, Skio, Loop) need extra handling. Initial purchase fires as a normal checkout_completed event. Recurring renewals do not fire client-side; they happen server-side when the subscription processor charges the card. To capture them, set up a webhook from the subscription app to your server, then forward to GA4 Measurement Protocol and Meta CAPI as offline conversions.
What to read next
Elevar and alternatives for the most-used tracking-app comparison. Advanced GA4 ecommerce tracking for schema details. CAPI setup guide for the cross-platform server-side delivery layer.