Shopify makes the Meta pixel easy to install and easy to install twice. This is the audit we run on every Shopify account before we touch a campaign: the failure points that are specific to Shopify, the checks that confirm each one, and what to do about what you find.
Shopify is the easiest platform to install a Meta pixel on and one of the easiest to get wrong. The reason is structural. On a custom site, the pixel lives in one place and you control that place. On Shopify, tracking is spread across at least four systems that do not talk to each other: your theme, Shopify's Customer Events layer, the apps you have installed, and Shopify's hosted checkout.
Each of those can add a pixel. None of them will tell you the others already did. A founder installs the Facebook and Instagram sales channel app in year one, hires a developer in year two who pastes the pixel into theme.liquid because the app install was not obvious, then adds a tracking app in year three that offers to set up the pixel for them. The store now has three install layers firing the same events and a reported conversion count that no longer matches the orders in Shopify.
The second structural issue is the checkout. Your theme does not run on Shopify's checkout pages. Anything you added to theme.liquid stops at the cart. The scripts that used to bridge that gap lived in checkout.liquid, and checkout.liquid is deprecated in favor of Checkout Extensibility, so those scripts no longer run. Purchase, the one event Meta optimizes hardest against, has to come from somewhere else entirely.
Third, Shopify's Customer Events runs pixels inside a sandbox. Custom pixels and app pixels execute in an isolated context with limited access to the page around them. That is good for store performance and security, and it makes debugging harder: a browser extension looking at your page may not see what a sandboxed pixel is doing. Setups that look broken from the outside are sometimes fine, and setups that look fine are sometimes missing half the funnel.
None of this is exotic. It is the default state of a store that has been running for a few years. That is why a Shopify pixel audit is a specific job with specific checks, not a glance at whether the pixel loads on the homepage.
Six things account for most of what we find. Work through them in this order, because the first one distorts everything downstream.
The most common finding by a wide margin. The Facebook and Instagram sales channel app installs the pixel through Shopify's Customer Events, and the same pixel ID also sits in theme.liquid, in a third-party tracking app, or in a Google Tag Manager container. Both layers fire on every page load. PageView and ViewContent double. If both layers also cover the cart, AddToCart doubles too.
Why it matters: your reported conversion volume and ROAS inflate, and Meta optimizes against a signal that overstates how often people act. Deduplication does not save you here. The event_id mechanism deduplicates a browser event against a matching server event. Two browser pixels firing the same event with different IDs are two real events as far as Meta is concerned.
A Purchase that arrives without value and currency tells Meta a sale happened but not what it was worth. Value-based bidding cannot work, ROAS reporting is empty, and catalog features lose their link to your products. On Shopify this usually happens when Purchase comes from a custom script somebody wrote quickly rather than from a proper integration. Check for value, currency, content_ids, and content_type on the Purchase event, and content IDs that actually match the product IDs in your catalog feed.
Shopify replaced checkout.liquid with Checkout Extensibility, so custom checkout scripts that used to fire Purchase are gone. Stores that never migrated their tracking lost the event and often did not notice for weeks, because clicks and traffic looked normal. Accelerated checkouts make it sharper: Shop Pay orders complete inside Shopify's checkout with no theme code involved at all. If Purchase depends on your theme, those orders are invisible.
Pixels added through Customer Events run sandboxed. They cannot read arbitrary parts of your page, they get a defined set of Shopify events to subscribe to, and outside tools cannot inspect them the way they inspect a script in your source. Two practical consequences: browser extensions can under-report what is actually firing, and any custom logic you were doing in a page-level script may not translate directly into a custom pixel. Plan verification through Events Manager instead of through the page.
The official Facebook and Instagram sales channel app installs the pixel and can send server-side events through the Conversions API, with deduplication handled between the two. Third-party tracking apps also offer server-side events. Running both at once is where stores get into trouble: two server-side senders and a browser pixel, with no shared event_id, produce inflated counts that are hard to trace. Pick one server-side sender and confirm what the other apps are doing before you leave them installed.
Consent apps and Shopify's customer privacy settings can block tracking for visitors who decline or ignore the banner, and in some regional configurations they block by default until consent is given. Your own testing passes because you accepted the banner months ago. The gap only shows up as a mismatch between Shopify sessions and Meta's event volume. Test in a private window from a region where your banner is enforced.
An hour, start to finish, with a real test order at the center of it. This is the sequence we use.
Before you test anything, find out how many pixels exist. Check four places: Settings then Customer events in Shopify admin, which lists app pixels and custom pixels. The Facebook and Instagram sales channel settings, which show the connected pixel and dataset. Your theme code, searching theme.liquid and any included snippets for fbq or connect.facebook.net. And your installed apps list, where tracking, analytics, and conversion apps often add their own pixel quietly. Write down every pixel ID you find. If the same ID appears twice, you have your first finding.
Open Events Manager, choose your dataset, and go to Test Events. Copy the test event code, open your store in a private window, and walk the full path: product page, add to cart, checkout, complete an order. Use a real order you can refund, or Shopify's test payment gateway with the store in test mode. Watch the events land as you go and check each one for duplicates and for the parameters that should be attached. This is the single most useful check on the list because it shows what Meta received, not what your page tried to send.
Install the Meta Pixel Helper extension and browse your storefront. It is fast at catching a second pixel ID on the page and at showing missing parameters on storefront events. Remember the sandbox: events fired through Customer Events may not surface here even when they are working. Treat a quiet Pixel Helper as a prompt to verify in Events Manager, not as proof of a broken install.
Open developer tools, go to the Network tab, and filter for requests to facebook.com. Each pixel fire is a request you can inspect. The ev parameter tells you the event name, the id parameter tells you which pixel ID sent it, and the remaining parameters show exactly what was attached. Two requests with the same ev value on a single page load is a duplicate you can prove.
In the Facebook and Instagram sales channel, confirm which dataset is connected and what the customer data sharing level is set to. You want the highest level the app offers (older versions call this Maximum), because that is what enables the server-side events. Then open every tracking or analytics app you found in step 1 and check whether it is sending Meta events as well. Turn off duplicated senders one at a time and re-run Test Events after each change so you know which change did what.
Back in Events Manager, look at event match quality on Purchase, the diagnostics tab for warnings Meta has raised, and whether deduplication is being recognized on your browser and server pairs. An event that fires but carries thin customer data is worth less than a clean one. If you want the deeper version of this, our full Meta pixel audit guide covers the scoring and the fixes across platforms. Not on Shopify? There are guides for WooCommerce, BigCommerce, GoHighLevel, ClickFunnels, Wix, Webflow, and Squarespace too.
If you spend real money on Meta, the answer is now. Browser events get dropped by ad blockers, by tracking prevention in Safari and Firefox, and by people who close the tab before the pixel finishes. The browser also knows less about the buyer than your order record does. The Conversions API sends the purchase server side with the email, phone, name, and address on the order, which lifts event match quality and gives Meta more of the signal it optimizes against.
On Shopify the simplest correct setup is the official Facebook and Instagram sales channel app with customer data sharing turned on at the highest level the app offers you. Older versions of the app call this Maximum. It sends both browser and server events for the same actions and handles the deduplication between them, so you do not have to build the event_id plumbing yourself. Third-party server-side apps can do the same job and sometimes add routing or enrichment on top, but only run one server-side sender at a time.
The check that matters: after CAPI is live, confirm in Events Manager that Purchase shows both browser and server as connections and that deduplication is being recognized. Two channels sending the same purchase without deduplication is worse than one channel sending it well.
Server-side tracking is not a replacement for a clean pixel, it is a second path for the same events. If you want the longer comparison, we wrote it up in Meta pixel vs Conversions API. And once your events are trustworthy, expect your reported numbers to move, which is the subject of why your ROAS numbers are wrong.
Most of step 1 and a good part of step 4 can be done for you. Our free Meta pixel audit scans your live store and reports what an outside browser can actually see: which pixel IDs load, whether the same ID appears in more than one install layer, what Shopify's pixel sandbox registry contains, which funnel events it can find across your product, collection, and cart pages, whether the storefront events it can read carry value, currency, and content IDs, and whether a consent banner is sitting in front of your tags. It also reads your Google Tag Manager container and Meta's public config for each pixel ID it finds.
The scan is upfront about the Shopify wrinkle: events inside hosted checkout, sealed web pixels, and Conversions API internals cannot be verified from outside, so it marks them as needs verification instead of pretending. Those are the items you confirm with Test Events in step 2, and we spell out exactly where the line sits on the audit methodology page. The scan takes about 20 seconds, needs no login and no pixel ID, and gives you a prioritized fix list to work from.
If you would rather someone else own the whole thing, that is what our Shopify service and broader eCommerce practice do: tracking verified before any campaign work, then kept verified while spend scales.
Almost always a double install. The Facebook and Instagram sales channel app adds the pixel through Shopify's Customer Events, and at some point the same pixel ID also got pasted into theme.liquid, into a tracking app, or into a Google Tag Manager container. Both layers fire on the same page load, so PageView and ViewContent count twice. The fix is to keep one install layer and remove the others. Deduplication by event_id only covers matching browser and server events, it does not cancel out two browser pixels.
The usual cause is that the Purchase event was never wired into Shopify's checkout. Checkout runs on Shopify's own pages, so theme code never executes there, and any script that lived in checkout.liquid stopped running once the store moved to Checkout Extensibility. Purchase has to come from the Facebook and Instagram sales channel app, a Customer Events pixel, or the Conversions API. Confirm it in Events Manager with Test Events on a real test order, or start with our free Meta pixel audit.
No, but it changes where the event has to come from. Shop Pay orders complete inside Shopify's hosted checkout, so nothing in your theme runs during that purchase. If your Purchase event depends on theme code or an old thank-you page script, Shop Pay and other accelerated checkout orders go unrecorded. If Purchase fires from the sales channel app or a Customer Events pixel, Shop Pay is covered like any other order.
Yes, if you spend meaningfully on Meta. Browser events get dropped by ad blockers, tracking prevention, and abandoned sessions, while your order record still carries the email, phone, and address that raise match quality. For most stores the official Facebook and Instagram sales channel app with customer data sharing at the highest level the app offers (older versions call this Maximum) is enough, and the section above covers when a third-party sender makes sense.
Pixel Helper reads the page it is running on. Events added through Shopify's Customer Events run inside a sandboxed context rather than directly in your page, so a clean install can still look quiet in the extension. It is a useful first look, not a verdict. Events Manager Test Events is the source of truth because it shows what Meta actually received.
Every Shopify account we take on starts with tracking verified end to end: one install layer, Purchase covered through checkout, CAPI live, deduplication confirmed. Scan your store yourself in 20 seconds, or have us walk it with you.