• 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:

  1. In Shopify admin, open Settings > Customer events and click Custom pixels.
  2. Look for your pixel under the Disconnected pixels section.
  3. 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.

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:

  1. Open Settings > Customer events and list every app pixel and custom pixel, then note which platforms each one sends to.
  2. Keep one sender per platform and disconnect the rest.
  3. Set transaction_id on 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:

  1. In Shopify admin, go to Settings > Customer events and click the custom pixel you want to test.
  2. Click Test. Your store opens with the Pixel Helper attached.
  3. Visit a product page, add to cart, and go through checkout.
  4. 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.

Talk to us

Data giving you a headache? We'll take it off your plate.

Tell us what's broken, or grab a time. Either way you hear from a person, not a sales script.

Send a message

We reply within one working day.

Add a few details (optional) The more we know up front, the faster we can tell you what's wrong and how to fix it.

Protected by an invisible spam check. Prefer email? olam@dolphinanalytics.co.uk

Calendly · 30 min

Book a call

Thirty minutes on Google Meet with the founder.

The booking lands on the same record as your message.