← All posts

Your pixel is probably broken. How to check in ten minutes

The quiet ways conversion tracking drifts, and a short checklist to catch it before your numbers do.

Tracking rarely breaks loudly. There’s no error message, no alert, no red banner. Conversions just get a little lower, or a little weirder, and you spend two weeks blaming the creative.

Most of the accounts I’ve looked at had something off. Not always a disaster. But almost always something.

And it matters more than it used to. If you’re sending profit or closed deals back to the platforms, like I talk about in Platform ROAS isn’t revenue, all of that sits on top of tracking. If the tracking is wrong, the platforms are learning from the wrong data.

The quiet ways tracking breaks

The source never gets stored. This is the big one. Someone lands from an ad with UTMs and a click ID in the URL, then browses to another page and converts there. The new page has no UTMs, nothing saved them, and the conversion shows up as direct or with no source at all. The landing page knew exactly where they came from. Nobody wrote it down.

There’s more than one pixel. Someone added a pixel through a Shopify app. Someone else added it in Tag Manager. An old agency hard-coded one in the theme two years ago. Now the same purchase fires two or three times, or fires to two different pixel IDs, and the platform can’t tell they’re the same sale.

Events fire at the wrong time. The purchase event fires when the checkout page loads instead of when the order goes through. The lead event fires when someone clicks the submit button, even if the form errors out. You get conversions that never happened.

Browser and server events don’t match up. You run the pixel and server-side events together, which is good. But Meta only treats them as one event if both send the same event ID and event name. If one side is missing the ID, or one sends “order_123” and the other sends “123,” every purchase counts twice.

A site update moved things. The thank-you page has a new URL. A new checkout, subscription app, or form tool took over, and nobody wired the events back up.

Values are wrong. The purchase fires with a value of 0, the wrong currency, or with tax and shipping included when it shouldn’t be.

The consent banner blocks more than you think. A cookie banner set up a little too strictly can quietly drop a big share of your conversions.

The ten-minute check

Grab a coffee and do this on your own site:

  1. Click your own ad, or add fake UTMs to your URL. Something like ?utm_source=test&utm_campaign=pixel-check. Then browse to a different page before converting.
  2. Convert. Place a test order or submit the form. Then check your store or CRM: did the source come through on that order or lead? If it says direct or blank, your UTMs aren’t being stored.
  3. Open the platform test tools while you do it. Meta has Test Events in Events Manager. Google has Tag Assistant. GA4 has DebugView. Each one shows events as they fire.
  4. Count the purchase or lead events. You want exactly one per platform. Two means duplication. Zero means it’s broken. If you see two different pixel IDs, you have more than one pixel installed.
  5. Check when it fired. It should fire after the order or form actually goes through, not on page load or button click.
  6. Check the value. Does it match the order total you expect, in the right currency?
  7. Check deduplication in Meta. In Events Manager, open the purchase event and look at how much of it is being deduplicated between browser and server.
  8. Compare a week of data. Pull last week’s orders or deals from your store or CRM and compare them to what each platform reported. A small gap is normal. A big gap in either direction needs a look.

The fix for disappearing UTMs

You need a small script that runs on every page. When someone lands with UTMs or click IDs in the URL, it saves them in the browser. When they convert later, on any page, it fills those values into the form or order.

Here’s the basic idea:

<script>
(function () {
  var KEYS = ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content",
              "gclid", "gbraid", "wbraid", "fbclid", "msclkid"];
  var params = new URLSearchParams(location.search);
  var found = {};
  KEYS.forEach(function (k) { if (params.get(k)) found[k] = params.get(k); });

  try {
    if (Object.keys(found).length) {
      found.landing_page = location.pathname;
      found.captured_at = new Date().toISOString();
      // keep the first touch, always update the last touch
      if (!localStorage.getItem("first_touch")) localStorage.setItem("first_touch", JSON.stringify(found));
      localStorage.setItem("last_touch", JSON.stringify(found));
    }
  } catch (e) {}

  // on submit, copy the stored values into hidden fields on the form
  document.addEventListener("submit", function (e) {
    var form = e.target;
    ["first_touch", "last_touch"].forEach(function (key) {
      var saved;
      try { saved = localStorage.getItem(key); } catch (err) {}
      if (!saved) return;
      var input = form.querySelector('input[name="' + key + '"]');
      if (!input) {
        input = document.createElement("input");
        input.type = "hidden";
        input.name = key;
        form.appendChild(input);
      }
      input.value = saved;
    });
  }, true);
})();
</script>

A few notes:

Catching it before your numbers do

The ten-minute check is great once. The problem is that tracking breaks again the next time someone touches the site, installs an app, or changes a form. And if you manage more than a handful of sites, checking each one by hand doesn’t scale. I get into that in Running fifty client accounts.

The real fix is checking continuously: comparing what the platforms report against your actual orders every day, and flagging the moment they drift apart.

Clean tracking is also what everything else is built on. You can’t put a dollar value on micro-actions you aren’t capturing, and you can’t tell if the landing page is the problem if you don’t trust the conversion numbers.

Where Apello fits

Apello watches this for you. It edits and adds tags and events, keeps the source attached from the first click to the conversion, compares what each platform reports against your real orders, and flags drift as soon as it starts, with a plain explanation of what broke and a proposed fix.