Conversion Tracking · Troubleshooting
How does Shopify Checkout Extensibility break my tracking, and how do I fix it?
Checkout Extensibility removed checkout.liquid and additional scripts, so any pixel or script you hardcoded into checkout stopped firing. Move every checkout and purchase event to the Web Pixels (customer events) sandbox, and send the purchase server-side through the Conversions API so the sale still reconciles.
What Shopify actually changed
For years, Shopify Plus stores controlled the checkout through checkout.liquid and the “Additional scripts” box in checkout settings. That is where most stores pasted their Meta Pixel, GA4 tags, TikTok pixel, Pinterest tag, and any custom purchase tracking. It worked because those scripts ran directly on the checkout pages and the order status page.
Shopify retired that model. checkout.liquid and the additional scripts field are gone, replaced by Checkout Extensibility. Checkout is now built from Shopify’s own upgraded checkout plus app extensions, and you no longer get to inject raw script tags into it. The order status page and post-purchase page moved with it.
So if your purchase event lived in additional scripts or checkout.liquid, it stopped firing the day your store migrated. The storefront tracking up to the cart still runs. Checkout and purchase are the part that goes dark.
Why the deadline matters
Shopify did not leave this open-ended. Additional scripts and checkout.liquid were deprecated, and stores that did not migrate had their old checkout customizations turned off. If you are on Plus and you have not done the migration work, assume the old tracking is either already dead or about to be.
The trap is that the storefront still looks healthy. PageView, ViewContent, and AddToCart keep reporting because those fire on theme pages, not checkout. Only the bottom of the funnel breaks. That is exactly the part you bid on, so a store can run for weeks thinking conversions are flat when really the purchase event quietly went to zero.
Where checkout tracking lives now
The replacement is the Web Pixels API, which Shopify surfaces in the admin as Settings, Customer events. This is a sandboxed JavaScript environment that subscribes to standard events: checkout_started, payment_info_submitted, checkout_completed, and the earlier funnel events like product_viewed and product_added_to_cart.
The sandbox is the important word. A Web Pixel runs in a Web Worker, isolated from the page DOM. It cannot read the page, cannot touch cookies the way an inline script could, and cannot rely on globals you used to set in the theme. You get a structured event payload and a small API for storage. Code written for additional scripts will not drop into a Web Pixel unchanged. It has to be rewritten against the event schema.
You have two ways to use it:
- App pixels. Meta, GA4 via Google and YouTube channel, TikTok, and Pinterest all ship Shopify apps that register their own Web Pixel automatically. For most stores this is the cleanest path. Connect the channel, confirm the pixel is registered under Customer events, and the platform handles the event mapping.
- Custom pixels. For anything the apps do not cover, you write a custom pixel in the Customer events screen, subscribe to the events you need, and forward them yourself. One boundary on this: Google documents that running Google tags inside the custom pixel sandbox is not a supported implementation, and enhanced conversions are one of the things that may not work correctly from there. Use custom pixels to forward events to your own endpoint or to platforms that support it, and keep Google Ads conversions on the Google & YouTube app or on the page itself. A theme-page conversion does not need the sandbox at all, which is the defect I shipped into my own build.
Rebuild the purchase event server-side
Client-side checkout tracking inside the sandbox is more limited than the old inline script, and browser-side events still get blocked by ad blockers, iOS, and ITP. So the reliable fix is to stop depending on the browser for the sale.
Send the purchase server-side. For Meta that is the Conversions API. For GA4 that is the Measurement Protocol, or a server-side GTM container. The cleanest version routes the order through a server endpoint that fires the purchase with the order ID, value, currency, and hashed customer data, then dedupes against any browser event using a shared event ID.
Shopify’s order webhook, or the checkout_completed event passed to your server, gives you a trustworthy purchase signal that does not depend on the customer’s browser finishing a script. That is the signal you want feeding your ad platforms, because it reconciles to real orders in Shopify.
A practical setup I keep coming back to:
- Web Pixels (app or custom) for the browser-side funnel events, so platforms still get the in-session signals they use for optimization.
- Conversions API and Measurement Protocol for the purchase, fired from the order, deduped by event ID.
- A single source of truth for revenue, which is Shopify orders, not the pixel.
How to confirm it is actually working
Do not trust the admin toggle. Verify each layer.
- Check Settings, Customer events, and confirm each platform’s pixel is registered and the custom pixels you expect are present.
- Place a real test order. Watch Meta Events Manager Test Events and the GA4 DebugView for
checkout_completedand purchase firing once, not zero times and not twice. - Reconcile a day of Shopify orders against purchases reported in Meta and GA4. If the platform numbers sit far below Shopify, something in the chain is dropping.
- Confirm deduplication. If browser and server both fire without a matching event ID, you will double-count and your ROAS will read better than it is.
Step 3 is the one worth doing properly, because the gap runs in both directions. On the one account in my Ecommerce Tracking Accuracy Benchmark where I could read both the order table and the ad account, the ad platform’s counted purchases over 90 days equalled 58.5% of the store’s entire order book, and its all-conversions purchase total equalled 65.9%, while the store’s own journey data classified none of those orders as paid. That is one account, N = 1, and it is enough to show the comparison is worth running on your own store.
If you migrated to Checkout Extensibility and your reported conversions fell off a cliff while Shopify revenue held steady, this is almost always the cause. The sale still happened. The tracking just lost the page it used to live on. Rebuild it on Web Pixels plus server-side events, then verify against real orders before you trust a single number in the ad dashboards.
Related questions
-
How do I set up the Meta Conversions API the right way?
How to set up the Meta Conversions API so server events deduplicate with the pixel, match well, and stop double-counting in platform reporting.
Read the answer
-
Why is my Shopify conversion tracking not working?
Shopify tracking breaks at predictable points: a missing Customer Events pixel, mismatched event names, or no deduplication. How I find the real cause.
Read the answer
-
What is server-side tracking?
Server-side tracking sends conversion data from your own server to ad platforms instead of the browser. How it works, and when to use it.
Read the answer
-
What conversion value should I send to Google and Meta, and how do I keep them reconciling?
How to pick the conversion value you send to Google Ads and Meta so both platforms reconcile with each other and with Shopify or your CRM.
Read the answer
Want this diagnosed in your account?
Same diagnosis,
run on your account.
Thirty minutes on the phone. I look at your spend, your tracking, and your search-term reports before the call. You walk out with a clear list of what is leaking and what to fix first.