Work through the checklist, most likely cause first, to find why events aren't arriving.
You installed the pixel, but events · last 7 days stays at 0 and last event says "never." Work down this list in order. Most cases are one of the first three.
Open the storefront in a browser, right-click, and choose View Page Source (not just Inspect — you need the raw HTML the server sent). Search for data-pixel-id. You should see:
<script async src="https://yourapp.example/api/px/script" data-pixel-id="px_..."></script>
What you'll see if it's missing: no match at all, or a data-pixel-id with an empty value. Both mean the script does nothing — it reads its pixel id from that attribute and returns early if the attribute is missing or empty.
Fix: on Shopify there is no snippet — open Settings → Tracking, click Enable the app embed, and switch nod. pixel on in the theme editor. Everywhere else, paste the exact snippet from Settings → Tracking just before the closing </head> tag, using the site template's global head or your tag manager's custom-HTML head slot. If you hand-typed or edited the snippet, re-copy it instead — a dropped attribute is the single most common cause of "no events."
The pixel stays dormant until analytics consent is explicitly granted. If no event arrives, your CMP may still be unknown/denied or may not be sending its live consent update.
Where to check: view source again and look for a window.__nodConsent assignment above the pixel tag. Also check your CMP's current consent state (declined vs. accepted) while testing.
What you'll see: if __nodConsent.analytics is missing or false, the pixel sends nothing at all. There is no flagged event, beacon, storage write, or network request.
Fix: accept analytics consent while testing and verify your CMP calls window.nod('consent', state) when the choice changes. Compare the wiring against Settings → Tracking → Website tracking → Consent. Shopify uses its Customer Privacy API directly.
If Settings → Tracking → Allowed sending domains has entries, the pixel only accepts events from those domains (and their subdomains). An empty list accepts events from anywhere.
What you'll see: nothing client-side — no JS error, no failed request in the sense of a visible 4xx. The collect endpoint returns 204 either way, so a rejected beacon looks identical to an accepted one unless you inspect the request in your browser's network tab.
Fix: make sure the allowlist includes the actual storefront domain the pixel loads on, not just a variant of it. example.com also covers shop.example.com. The mistake that actually breaks this: allowlisting only shop.myshopify.com while the storefront is served from a different custom domain — the allowlist won't cover that custom domain until you add it. When in doubt, clear the allowlist to accept all domains, confirm events start arriving, then narrow it back down carefully.
If you've set up a custom pixel domain (e.g. px.yourshop.com) but it hasn't finished verifying, the copyable snippet in Settings → Tracking still points at the shared nod domain — and that's fine, it keeps working. The snippet only switches to your custom host once the domain shows "Verified — serving first-party."
This only causes missing events if you manually edited the snippet to point at your custom domain before it verified. In that case requests go to a host that isn't ready yet and fail.
Fix: use the snippet exactly as shown on the Tracking page rather than hand-editing the host. Check the domain card's status badge — "Waiting for DNS" or "DNS not pointing here yet" means it isn't ready. Click "Check DNS" to refresh the status once you've added the CNAME.
The pixel overview counts events over the trailing 7 days and shows a relative "last event" time. If you just installed the snippet, a single test pageview should move "last event" to "just now" almost immediately — this isn't a delayed batch process.
If "last event" already shows something recent but the 7-day count looks lower than expected, that's a different problem — see the data checklist, not this article.
Non-purchase events are capped at 20,000 per hour per pixel, plus 600 per hour per visitor. Purchase events (nod('track', 'Purchase', ...) or nod('purchase', ...)) use their own separate bucket of 2,000 per hour and never compete with pageview traffic. You'd need extreme volume to hit either ceiling, and the limiter fails open — if its own check breaks, events are still accepted. If you suspect this, it will show up as intermittent gaps under heavy load, not a total absence of events.
If you've worked through the list above and events still aren't arriving, contact support with:
window.__nodConsent is set to.That's usually enough to spot the cause without back-and-forth.