- Shopify
- Custom Pixels
- Customer Events
- GA4
- Ecommerce Tracking
Shopify Custom Pixel Not Firing? Why, and the Fix
By Dolphin Analytics team · Published 8 Oct 2026 · Last checked 8 Oct 2026
TL;DR
A Shopify custom pixel usually breaks for one of six reasons: it was never connected, consent blocks it, the sandbox rewrites page URLs, the code scrapes the theme's DOM or dataLayer, checkout_completed fires on an upsell page, or an app pixel sends the same purchase. Each has a check in Customer events and a code fix. We run them in this order for Shopify stores and agencies.
Your Shopify custom pixel is installed, the admin says nothing is wrong, and purchases in GA4 or your ad platforms still don’t match the orders. We fix this for Shopify stores and the agencies that run them most weeks, and the pixel is rarely missing. It is usually loading for fewer people than you think, reporting the wrong page, or sending a purchase that something else also sends. Teams reach us pulling their hair out with data challenges like this one, so below is the order we check a custom pixel in, with the fix for each fault. If you’d rather hand it over, our tracking service covers exactly this work.
What is a Shopify custom pixel, and why does it break?
A Shopify custom pixel is JavaScript you paste in under Settings > Customer
events, which subscribes to Shopify’s customer events and forwards them to
GA4, Meta or another tool. Shopify loads custom pixels in a lax sandbox: an
iframe with only the allow-scripts and allow-forms permissions, which
cannot access the top frame of the page (Shopify’s web pixels
documentation).
That sandbox is where most of the breakage starts. Shopify says features that
scrape the DOM for information or write to the DOM won’t work the same, or
won’t work at all, and that window.href returns the sandbox URL instead of
the page the shopper is on (Shopify’s web pixels
documentation). Old
tracking snippets assumed the opposite on every line.
If you’re still moving scripts out of the retired Additional Scripts box, start with our Checkout Extensibility migration guide. This post picks up after that: the pixel exists, and the data is still wrong.
Is the custom pixel actually connected?
A Shopify custom pixel only collects data once it is connected, and saving the code is not the same thing. Under Settings > Customer events > Custom pixels, Shopify lists each pixel as Connected or Disconnected, and a pixel under Disconnected pixels needs you to click Connect and confirm (Shopify’s guide to managing custom pixels).
The check takes a minute:
- In Shopify admin, open Settings > Customer events and click Custom pixels.
- Look for your pixel under the Disconnected pixels section.
- If it’s there, click Connect on its row, review the notice, then click Connect again.
Disconnecting a pixel doesn’t delete it (Shopify’s guide to managing custom pixels), so a pixel someone switched off during testing can sit there looking finished. When we audit a store, this is the first row we read.
Is the consent setting stopping the pixel loading?
A connected custom pixel still won’t load for a visitor who hasn’t given the permissions it asks for. Shopify’s pixel manager only loads a pixel when the visitor has granted every purpose the pixel declares as required, and the purposes are analytics, marketing, preferences and sale of data (Shopify’s pixel privacy documentation). Shopify also states that app pixels and custom pixels only track behaviour with consent (Shopify’s guide to replacing additional scripts).
So a pixel that worked through the old checkout script can look broken after the move, when it is in fact respecting consent the old script ignored. The fix is in the pixel’s Permission setting, where you choose Required and tick the purposes, or choose Not required (Shopify’s guide to managing custom pixels).
Our rule of thumb: tick only the purposes the tag genuinely serves. Analytics for a GA4 pixel, marketing for an ad platform pixel. A GA4 pixel that also demands marketing and sale-of-data consent loads for fewer shoppers than it needs to. If your banner and Shopify’s purposes don’t line up, our post on cookie consent blocking GA4 covers the banner side.
Why does GA4 show sandbox URLs instead of my store pages?
GA4 records odd page addresses because the custom pixel runs in an iframe,
and the browser’s own location inside that iframe is the sandbox, not the
store page. Shopify’s GTM tutorial says page URLs may include sandbox details
and recommends turning off GA4’s automatic page tracking, then tracking pages
yourself from the standard page_viewed event (Shopify’s GTM custom pixel
tutorial).
Every Shopify event carries the real page in event.context.document, which
holds location, referrer and title (Shopify’s page_viewed
documentation).
Google’s own guide disables automatic page views with send_page_view: false
and warns that sending manual page views without disabling them can create
duplicates (Google’s GA4 page view
guide).
Put together, the fix looks like this:
// Load gtag inside the pixel's sandbox, with automatic page views off
const tag = document.createElement("script");
tag.async = true;
tag.src = "https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX";
document.head.appendChild(tag);
window.dataLayer = window.dataLayer || [];
function gtag() { window.dataLayer.push(arguments); }
gtag("js", new Date());
gtag("config", "G-XXXXXXX", { send_page_view: false });
// Send the real store page, not the sandbox URL
analytics.subscribe("page_viewed", (event) => {
const doc = event.context.document;
gtag("event", "page_view", {
page_location: doc.location.href,
page_referrer: doc.referrer,
page_title: doc.title
});
});
Swap G-XXXXXXX for your GA4 Measurement ID. The page_viewed event runs on
the online store, checkout and Order status pages (Shopify’s page_viewed
documentation),
so one subscription covers the whole journey.
Is the pixel trying to read the theme’s DOM or dataLayer?
A custom pixel that reads the theme’s dataLayer, clicks or form fields
finds nothing, because the lax sandbox cannot reach the top frame
(Shopify’s web pixels
documentation). The
window.dataLayer inside the pixel is a new, empty one that belongs to the
iframe. Your theme’s GTM container never sees it, and it never sees the
theme’s.
Shopify’s GTM tutorial also notes that some GA4 enhanced measurement events, such as outbound link clicks, can’t fire automatically inside the sandbox and have to be built as custom events (Shopify’s GTM custom pixel tutorial).
The fix is to hand the pixel the data instead of letting it go looking. From
the theme, publish your own event with
Shopify.analytics.publish("my_store:event_name", data), then subscribe to
it in the pixel and read the payload from customData (Shopify’s guide to
publishing custom
events).
// In the theme: publish what the pixel can't see
Shopify.analytics.publish("my_store:newsletter_signup", { form: "footer" });
// In the custom pixel: receive it and forward it to GA4
analytics.subscribe("my_store:newsletter_signup", (event) => {
gtag("event", "sign_up", { method: event.customData.form });
});
Shopify asks for a prefix on custom event names so they don’t collide with standard events (Shopify’s guide to publishing custom events). The full storefront and checkout split is laid out in our Shopify Google Tag Manager setup guide.
Why is the purchase event missing for some orders?
A custom pixel can miss purchases because checkout_completed doesn’t
always fire where people assume. Shopify triggers it once per checkout,
usually on the Thank you page. With post-purchase upsells it fires on the
first upsell page instead and does not fire again on Thank you, and if the
page fails to load, it isn’t triggered at all (Shopify’s checkout_completed
documentation).
Two things follow from that. Code that waits for a Thank you page URL, or
for a page_viewed on Thank you, will skip every order that went through an
upsell, so subscribe to checkout_completed itself. And a small shortfall
between Shopify orders and pixel purchases is expected, because the pixel
depends on a page loading in the shopper’s browser and the order does not.
On where that shortfall stops being normal, our working benchmark is this:
A gap of roughly 10 to 15% between Shopify and GA4 purchases is normal; beyond that is worth investigating.
Why are purchases counted twice after adding a custom pixel?
Double counting after a custom pixel goes live almost always means a second sender. Shopify warns that leaving an old Thank you page script running alongside a pixel makes the third-party platform count the event from both (Shopify’s guide to replacing additional scripts). The same happens when a sales channel app installs its own app pixel for GA4 or Meta and your custom pixel sends that purchase too.
Fix it in this order:
- Open Settings > Customer events and list every app pixel and custom pixel, then note which platforms each one sends to.
- Keep one sender per platform and disconnect the rest.
- Set
transaction_idon every GA4 purchase to the Shopify order ID. Google Analytics deduplicates purchases with the same transaction ID, and an empty string makes it deduplicate all of them (Google’s GA4 transaction ID help page).
For Meta, a browser pixel plus the Conversions API needs a shared event ID, which we cover in Meta CAPI not working. The GA4 side has its own walkthrough in GA4 duplicate purchase events.
How do you test a Shopify custom pixel?
Test a custom pixel with Shopify’s Pixel Helper, not Google Tag Assistant. Shopify’s GTM tutorial says Tag Assistant’s troubleshooting can’t detect Google tags loaded inside a custom pixel (Shopify’s GTM custom pixel tutorial), which is why so many teams see “no tag found” on a pixel that works.
The steps, from Shopify’s guide to testing custom pixels:
- In Shopify admin, go to Settings > Customer events and click the custom pixel you want to test.
- Click Test. Your store opens with the Pixel Helper attached.
- Visit a product page, add to cart, and go through checkout.
- Expand the Pixel Helper dialog. A green dot means the event was subscribed to and its callback ran; a red dot means the callback failed, and the helper shows the uncaught error.
The helper tests one custom pixel at a time, and its event log clears when you move to a new page (Shopify’s guide to testing custom pixels), so read it before you click on. If a dot stays red, open the browser’s developer tools with the pixel’s iframe selected: the console shows the errors your code throws, and the network tab shows whether its collect requests to GA4 ever left the browser. Then confirm the receiving end in GA4 DebugView; our DebugView troubleshooting guide covers what to do when that stays empty too.
When should you call someone instead of fixing the pixel yourself?
Call someone when the faults stack up. If the pixel is connected, the consent purposes are right, Pixel Helper shows green dots, and GA4 or your ad platforms still sit well below Shopify’s orders, the problem has moved outside the pixel. The same goes for a store running several app pixels, upsells, a consent banner and a Meta Conversions API setup at once: each interacts with the others. Shopify itself says custom pixels are unsupported and points merchants who need help to a Partner (Shopify’s custom pixels guide).
We do this repair for agencies and in-house teams, and it’s usually a scoped fix rather than a rebuild. One recent example of how much rides on getting it right:
Restored accurate conversion tracking within 48 hours after a Shopify Checkout Extensibility upgrade broke it, avoiding an estimated $1.5M in wasted ad spend and mis-optimised Google Ads.
If your custom pixel numbers stopped adding up, tell us what’s broken, or book a call, and you’ll get a considered reply from a person. To see what fires on your storefront and checkout pages from the outside first, scan the URL with Sonar. For purchases that stopped completely after the checkout change, our post on Shopify checkout tracking not working maps each symptom to its cause.
Frequently asked
What is a Shopify custom pixel?
A Shopify custom pixel is JavaScript you add under Settings > Customer events that subscribes to Shopify's customer events, such as page_viewed and checkout_completed, and sends them to a tool like GA4 or Meta. Shopify loads custom pixels in a lax sandbox, an iframe that cannot reach the top frame of the page, which is why code written for the theme often fails inside one.
Why is my Shopify custom pixel not firing?
Check three things first. The pixel must show as Connected under Settings > Customer events, because a pixel that is disconnected never loads. Its Permission setting must match your consent banner, because Shopify only loads a pixel when the visitor has granted every purpose it lists as required. Then run Shopify's Pixel Helper with the Test button to see whether each subscribed event's callback succeeds.
Why does GA4 show strange page URLs from my custom pixel?
Inside the sandbox, the browser's own location returns the sandbox URL rather than the store page, so GA4's automatic page views record the wrong address. Turn off automatic page views with send_page_view set to false, then send page_view yourself from Shopify's page_viewed event, using event.context.document.location.href as page_location.
Can I debug a Shopify custom pixel with Google Tag Assistant?
Not reliably. Shopify's own GTM tutorial says Tag Assistant's troubleshooting cannot detect Google tags loaded inside a custom pixel. Use Shopify's Pixel Helper from the Test button in Customer events, the browser console and network tab for the pixel's iframe, and GA4 DebugView for what actually arrived.
Why are purchases counted twice after adding a custom pixel?
Usually because something else still sends the same purchase: an old Thank You page script, or an app pixel such as a sales channel app firing alongside your code. Keep one sender per platform, and give every GA4 purchase a real transaction_id so Google Analytics can deduplicate repeats.