Skip to main content
PandaCodeGen
+1 (302) 773-8982

info@pandacodegen.com

Back to Blog
Ad Tracking · Guide

Your Facebook Ad Tracking Isn't Broken by Accident. Here's How to Diagnose and Fix It.

iOS opt-outs, ad blockers, Safari's 7-day cookie cap, and Shopify's checkout changes quietly eat your conversion signal. Meta reports a worse ROAS than you actually got, then optimizes toward the wrong people. Here is the diagnosis, and the server-side fix.

Hassan Jamal

Hassan Jamal·Jul 6, 2026·11 min read

Key Facts

  • Browser pixel tracking loses a large share of conversions to iOS App Tracking Transparency, cookie loss, Safari's 7-day cap, ad blockers, and Shopify's checkout.liquid removal
  • Meta can't credit sales it can't see, so it under-reports ROAS and optimizes on partial data
  • The fix is server-side tracking through the Meta Conversions API: events sent from your server with strong identifiers, deduplicated against the pixel by a shared event ID
  • On Panda Patches, the store we build and run, this setup lifted credited Lead conversions about 10% and pushed Lead Event Match Quality to roughly 9.0/10

A while back, the Meta ads for Panda Patches looked like they were slipping. Same creative, same audiences, but the reported numbers were softer than the bank account suggested. The ads weren't the problem. The tracking was. Once we wired up proper server-side tracking with the right identifiers and Meta's Conversions API, Lead conversions Meta could actually credit went up about 10%, and Event Match Quality for the Lead event reached roughly 9.0 out of 10. Panda Patches is a custom Next.js store we build and run, and it puts real paid traffic on the exact stack described below, so these are first-party numbers, not a case study we bought.

If your ads suddenly look worse than they used to, read this before you touch a single budget. Most of the time the campaign is fine. The pipe carrying the data back to Meta is leaking.

Why is my Facebook ad tracking not working all of a sudden?

Because the old way of tracking, a JavaScript pixel running in the visitor's browser, depends on things that browsers and Apple have spent five years taking away. The pixel still loads, so it looks fine in a quick check, but a growing slice of your customers are invisible to it.

  • iOS App Tracking Transparency (ATT). Since iOS 14.5 (2021), Apple shows the "Ask App Not to Track" prompt, and the large majority of users tap it. When an opted-out Facebook or Instagram user lands on your site, Meta's ability to connect the visit to their account is heavily restricted. Industry estimates put the visibility loss from this alone at 30 to 50 percent.
  • Third-party cookies are gone or blocked. The pixel historically leaned on cookies to recognize people. Safari and Firefox block third-party cookies outright. No cookie, no match.
  • Safari's 7-day cookie cap (ITP). Safari caps cookies set by JavaScript at seven days. Someone clicks your ad Monday and buys the following week? Safari already wiped the cookie that linked the sale to the click. The purchase shows up as "direct" and your ad gets no credit.
  • Ad blockers and consent banners. Ad blockers stop the pixel's network call from ever reaching Meta. Consent banners hold the pixel back until the visitor clicks accept, and plenty never do. This is why a pixel can fire perfectly in incognito and still miss real customers.
  • Shopify's checkout.liquid deprecation. Shopify removed support for checkout.liquid and custom scripts on the Thank You and Order Status pages (Plus stores hit the deadline August 28, 2025; other plans follow in 2026). Any conversion tracking living on those pages stopped firing overnight.

None of these are your campaign's fault. They're the environment your pixel runs in, and that environment keeps getting more hostile.

How can I tell my tracking is actually broken (and not just my ads underperforming)?

You look for the gap between what Meta says happened and what really happened. Tracking problems leave fingerprints. Run through this checklist:

  • Meta reports fewer sales than your store. Compare Meta's reported purchases to the orders in your store admin for the same window. A persistent shortfall (Meta low) is the classic under-reporting signature.
  • Your Event Match Quality (EMQ) is low. Open Events Manager and check the EMQ score on your key events. Below 6 is weak. A Purchase or Lead event should sit in the 7 to 10 range.
  • Events Manager shows lots of unmatched or browser-only events. Important events arriving with thin data is signal you're paying for but Meta can't use.
  • Reported ROAS dropped without a real change. Same creative and audiences, suddenly worse numbers, usually lines up with a platform change (an iOS update, a checkout migration), not your campaign.
  • Pixel works in incognito but misses real traffic. That points to ad blockers or a consent banner suppressing the pixel for normal visitors.
  • Test Events shows less than reality. Open Events Manager's Test Events tool, complete a purchase or lead on your live site, and watch what arrives. If your own test conversion shows up thin or not at all, so do your customers'.
  • You're relying on the pixel alone. If you've never set up server-side tracking, assume you're leaking. In 2026, pixel-only is the broken default.

The one to fixate on is the first: the discrepancy between Meta-reported orders and real orders. When we built the live tracking dashboard for Panda Patches, it laid this bare. Only about half the sales were reaching Meta with their full story attached. Meta knew the other half happened, but couldn't connect them to an ad, so it couldn't learn from them. Meta optimizes against the data it can see. Feed it half the picture and it spends your budget chasing the wrong people.

What's the actual difference between the pixel and server-side tracking?

The pixel runs in the customer's browser and is at the mercy of everything that browser allows. Server-side tracking sends the event from your server straight to Meta, where Apple, ad blockers, and cookie rules can't reach it. Apple cannot block a server-to-server call.You don't pick one; you run both and let Meta deduplicate.

← Swipe to see more →

Pixel only (browser)Pixel + server-side (CAPI)
Survives iOS ATTNo, opted-out users are largely invisibleYes, the server event still sends
Survives ad blockersNo, the network call gets stoppedYes, the call comes from your server
Survives Safari 7-day capNo, delayed conversions get lostYes, server events aren't cookie-dependent
Match quality (EMQ)Typically low, thin identifiersHigher: email, phone, fbp, fbc, IP, user agent
Optimization signal to MetaPartial, Meta learns from a fraction of salesFuller, Meta credits and learns from far more

The pixel is a guest in someone else's browser. Server-side tracking is a message you send from your own house.

How does server-side tracking actually fix it?

It gives Meta a clean, complete copy of every conversion, with enough detail to confidently match it to a real person, sent from a place nothing can block. Here's what "done right" looks like:

  • Send the event from your server, not just the browser. When a customer completes a purchase or submits a lead, your server fires the event to Meta's Conversions API directly. No browser, no cookie dependency, no ad blocker in the path.
  • Capture the identifiers Meta needs to match: fbp (the Facebook browser ID), fbc (the click ID from the ad URL), hashed email and phone (email is the single strongest identifier), plus IP address and user agent captured server-side. For Google, the equivalent is gclid plus enhanced conversions.
  • Hash the personal data correctly. Email and phone run through SHA-256 before they leave your server, lowercased and trimmed, phone with country code, exactly to Meta's spec. Meta never sees raw data, only hashes.
  • Deduplicate with a shared event ID. The pixel and the server send the same purchase with the same eventID; Meta counts it once. This is the step people skip, and it's why sloppy setups double-count.
  • Watch EMQ climb. On Panda Patches, the Lead event reached about 9.0 out of 10, and Events Manager reported roughly 10% more Lead conversions than the pixel had caught alone. That's optimization signal that was on the floor.

Email plus fbc alone can move an EMQ score from the low 3s into the 7s. If you want the deeper breakdown of what this build involves and costs, we wrote it up in Meta Conversions API setup cost. If your symptom is specifically "spending more, seeing fewer orders," that framing is in spending more on ads, fewer tracked orders.

Want to know how much signal your store is leaking?

Drop your store URL when you book. We'll compare your Meta-reported orders to reality, check your EMQ live on the call, and tell you straight whether server-side tracking is worth it for your spend.

What does "good" tracking look like once it's fixed?

Good tracking is boring, in the best way. The numbers stop arguing with each other.

  • Meta-reported orders line up closely with your real orders. The discrepancy shrinks to a small, explainable gap.
  • Event Match Quality sits in the 7 to 10 range on your money events (Purchase, Lead).
  • Events Manager shows rich, matched events with identifiers attached, not thin browser-only pings.
  • Your reported ROAS reflects reality, so you can trust it when deciding where to scale.
  • Platform changes stop breaking you. The next iOS update or checkout migration doesn't wipe a third of your data, because your conversion source lives on your server.

The payoff isn't just cleaner dashboards. When Meta can see the full set of conversions, it optimizes toward people who actually buy. Better signal in, better spend out.

Should I use a third-party tracking app or build it into the site?

Quick Answer

An app is faster to switch on and a recurring cost forever. A built-in setup is more work up front and then it's just yours. For a store spending real money on ads every month, owning the pipe usually wins.

Most tracking apps are middleware: a monthly subscription sitting between your store and Meta, and the day you stop paying, your tracking goes with it. You're renting your own conversion data.

PandaCodeGen builds server-side tracking directly into the site, so it's owned, with no monthly middleware tax. Server-side Meta CAPI is included in our Scale tier ($5K to $10K), and it can be added to an existing site too, it doesn't require a full rebuild. It's part of how we do e-commerce development and custom engineering: the tracking is yours, wired in once, and it doesn't expire when an invoice does.

Fixing Meta Ad Tracking If You're on Shopify

Everything above describes wiring the Conversions API into a custom-built stack, the way we did it for Panda Patches, our own Next.js store. A lot of the store owners reading this run Shopify instead, and the fix path there is genuinely different. Shopify has shipped its own native Meta Conversions API support directly into the platform, so most Shopify merchants don't need to write server code, hash identifiers, or build a deduplication pipeline from scratch. You're turning on an integration Shopify and Meta already built and maintain, not building one.

Quick Answer

On Shopify, look for server-side tracking inside Shopify's own Marketing settings and the official Meta (Facebook & Instagram) sales channel, usually alongside Settings > Customer events. The exact label shifts as Shopify updates its admin, so if what you see doesn't match, search "Meta" or "Facebook" from Shopify admin search and look for the conversions API or server-side tracking option attached to your ad connection.

Connect your Meta ad account and catalog through that channel, then check that the data-sharing setting is on the highest option available rather than the default. That one setting is usually the difference between Shopify sending Meta a thin, browser-only event and a full server-side event with order, email, and phone data attached.

Why is Shopify's server-side tracking setup simpler than the custom Next.js path above?

Because Shopify owns the checkout. On a custom stack, you build the server, capture the identifiers, hash them correctly, and deduplicate against the pixel yourself, which is the work described earlier in this post. On Shopify, the platform already sits between the buyer and the order data: it knows the email, phone, and order total the moment checkout completes, and its native integration passes that straight to Meta's Conversions API on your behalf.

This is also why Shopify pushed merchants toward the native integration in the first place. When Shopify removed checkout.liquid and custom scripts on the Thank You and Order Status pages, it closed off the old workaround of pasting a custom pixel snippet onto the checkout page. The native, platform-level Conversions API connection is the supported replacement, not a workaround, and it keeps working through checkout changes that would otherwise break a custom script.

Why aren't my Shopify sales showing up in Meta Ads Manager?

Run the same check described earlier in this post: compare Meta's reported purchases to your actual Shopify order count for the same date range. If Meta is under-counting, the cause on Shopify is almost always one of two things.

  • The app is installed but server-side sharing isn't actually turned on. Plenty of stores connected the Facebook & Instagram channel years ago for the browser pixel and never revisited it once Shopify added the conversions API layer, so they're still effectively pixel-only.
  • Event Match Quality is low. Open Events Manager and check the EMQ score on your Purchase event, same as described earlier in this post. A low score on Shopify usually means the channel isn't passing hashed email and phone with the order, not that the integration itself is broken.

Neither of those is a code problem. Both are a settings problem, which is the practical upside of being on Shopify: the fix is a checklist, not a build.

How do I fix Shopify tracking after iOS privacy changes?

The same way described throughout this post, just through Shopify's own toggle instead of custom code. iOS App Tracking Transparency restricts what the browserpixel can see once a customer opts out. It has no power over a server-to-server call, which is exactly what Shopify's native Conversions API integration sends. Turn it on, connect your ad account, and set data sharing to the highest level, and iOS opt-outs stop being a blind spot for that share of your traffic.

The EMQ mechanics behind that fix are the same ones behind the Panda Patches numbers referenced earlier in this post. Panda Patches isn't a Shopify store, it runs on our own Next.js and Square stack, but it hits Meta's Conversions API and EMQ scoring the same way any CAPI integration does. Feeding Meta a full set of identifiers, email, phone, fbp, fbc, is what moved Lead EMQ to roughly 9.0 there. A Shopify store with the native integration fully connected and data sharing maxed out is feeding Meta that same kind of identifier set, so the EMQ lift follows the same logic, even though the plumbing underneath is Shopify's, not custom code.

If your native integration is already connected, data sharing is already maxed out, and EMQ is still weak, or you're running a headless Shopify setup where checkout doesn't sit on Shopify's standard hosted flow, that's closer to the custom-stack problem described in the rest of this post. Book the free tracking audit below and we'll tell you which situation you're actually in.

Stop Optimizing on Half Your Data

Free tracking audit. We'll measure the gap between your real orders and what Meta sees, then quote a fixed price to wire server-side CAPI into your site, owned, no monthly middleware.

Frequently Asked Questions