pixellint

21 guides · Pixels and tags

What fires in the browser

A pixel is an HTTP request with a job: impression, click, page, or conversion. The 1x1 GIF is one transport. sendBeacon and fetch are the others. These pages are the failure modes you will actually hit.

Validate a pixel or CAPI All docs

A pixel is an HTTP request with a job PixelsPMsmarketersengineers A tracking pixel is an HTTP request that records an ad impression, click, page view, or conversion. The transport may be a 1x1 image GET, navigator.sendBeacon, or fetch. Email open pixels and VAST Impression beacons are the same job on different surfaces. An image cannot hash an email Pixelsengineersmarketers A 1x1 image pixel can only send what fits in a GET URL, about two thousand characters in practice. Floodlight and LinkedIn Insight still ship images. fbq, gtag, and ttq can POST a body, read cookies, and hash emails. CSP and noscript treat the two transports differently. Noscript is a different request Pixelsengineersmarketers A noscript image pixel is the fallback when JavaScript does not run. Meta uses noscript=1 on facebook.com/tr. It is a different request, not a second copy of the JS event. Ad blockers that list the host will block the image too. Dedup with event_id if both can fire. Impression and click are not the same URL PixelsmarketersPMsengineers An impression pixel fires when the creative loads and should return 200 with a 1x1 or 204. A click tracker fires on click as a 302 chain. Never 302 an impression to a landing page. View-through is a report setting, not a third pixel. Thank-you page pixels miss the backend sale PixelsPMsmarketersengineers A conversion pixel fires in the browser on the thank-you page. An MMP postback is a server-to-server GET or POST with macros expanded at conversion time. CAPI is a JSON POST to the vendor. They fail in different ways. Unexpanded macros on a fired postback are a trafficking bug. The vendor host cannot see your cookie jar PixelsengineersPMs Third-party cookies on facebook.com or google-analytics.com are blocked or partitioned in Safari, Firefox, and Chrome. First-party pixels set _fbp and _ga on your domain. CHIPS partitions third-party cookies by top-level site. ITP expires tracker-like storage. Matching moved to click ids and server events. A cached impression is a lie Pixelsengineersmarketers Impression pixels need a unique query value so CDNs and browsers do not collapse thousands of impressions into one cached response. Floodlight uses ord, and unique counting also needs num. Ad servers expand [CACHEBUSTER]. Do not put PII in ord. Click URLs do not need this trick. A 200 in a click chain is a dead end Pixelsengineersmarketers Click trackers are redirect chains. Each hop can append or drop gclid, fbclid, or an MMP id. A 200 in the middle of the chain is a broken click. http to https and apex to www redirects that drop the query string are the usual paid-search outage. Debug with curl -sIL. The URL changed. The pixel did not. PixelsengineersPMs Single-page apps do not reload the document. If you only fire PageView on first load, checkout and thank-you routes are invisible. Hook history. React 18 Strict Mode double-mounts and will double Purchase. Meta CAPI event_source_url must be the current route, not the first URL of the session. The pixel ran in the wrong frame Pixelsengineers A pixel inside an iframe sees a different referrer, a different cookie jar, and often a different CSP. Payment iframes (Stripe, PayPal) make thank-you pixels report stripe.com as the source. Fire from the parent on postMessage, or from the server when the webhook says paid. Creative iframes measure the ad, not the landing page. UTM is not a click id PixelsmarketersPMsengineers utm_source, utm_medium, utm_campaign, utm_content, and utm_term are for your analytics property. Google Ads, Meta, and TikTok attribute paid clicks with gclid, fbclid, and ttclid. UTM is not a click id. Casing splits sessions. Do not put gclid in utm_content and expect Ads to see it. Purchase does not belong on the landing page PixelsmarketersPMsengineers PageView belongs on the landing page, where click ids are stored. Purchase belongs on the thank-you page, once. Hosted checkout (Shopify, Stripe Checkout) often means the thank-you page is another host, so cookies and click ids must travel or the conversion fires as a new user. Firing Purchase on every landing inflates ROAS until the platform discounts you. Not every 200 was a person PixelsengineersPMsmarketers Prefetch, Slack unfurls, Gmail image proxies, and link scanners fire pixels without a user. Platforms filter invalid traffic in the UI. Your BigQuery export of raw hits will not match. Gate conversion tags on a real order id, not on DOM Ready of a public URL. The tag ran. The request did not. PixelsengineersmarketersPMs Ad blockers drop known pixel hosts from EasyList and similar lists. GTM preview can say the tag fired while facebook.com/tr never leaves the machine. Noscript does not bypass a host block. Recovery is CAPI or sGTM on a first-party collector you operate, not a second request to the same listed host. no-referrer means the collector guesses Pixelsengineers A strict Referrer-Policy strips path and query from document.referrer. Vendors that key off the referring URL lose landing-page context and click ids in the referrer. event_source_url and page_location must be location.href, the current document, not document.referrer. no-referrer makes the collector guess. buyer@example.com in the query is a finding PixelsengineersPMs Raw emails, phones, and names in a pixel URL land in vendor logs, CDN logs, and Referer headers. Meta flags unhashed emails on facebook.com/tr as vendor.meta.pii.unhashed_email. Hash SHA-256 of a normalized email in a body field, or use CAPI. Image pixels cannot hash in the browser. The fired URL still says CACHEBUSTER Pixelsengineersmarketers Macros use three syntaxes: [NAME], ${NAME}, and {{NAME}}. They must expand before a pixel fires. They never belong in scheme, host, or userinfo. Mixed syntax in one URL is a trafficking smell. gdpr_consent=1 is valid base64 and not a TC String. Pixellint core encodes these as macro and privacy rules. Say whether it has fired Pixelsengineersmarketers A template URL is what the ad server stores. A fired URL is what the browser requested. Pixellint artifact state is unknown, template, or fired. Template may contain macros. Fired may not. Unknown stays conservative. CI needs two fixtures, two states, one job. A first-party hostname is still their collector PixelsengineersPMs Serving a vendor collector from metrics.example.com via DNS CNAME can dodge some blocklists. Safari classified CNAME-cloaked trackers. Certificate automation and subdomain takeovers become your incident. Server-side GTM on infrastructure you own is a different design: you send the event, you do not pretend facebook.com is you. PageView fired twice on one load Pixelsengineersmarketers Two PageView hits per load come from initializing fbq and GTM's Meta tag, from React 18 Strict Mode, or from History Change plus Container Load. The Network tab shows two /tr?ev=PageView or two /g/collect en=page_view hits. Deduplicate or remove a tag before you chase a platform bug. VAST start is still an impression pixel Pixelsengineersmarketers VAST Impression, Tracking start/quartile/skip/progress, and ClickThrough are three pixel contracts on one tag. A fired start that still contains CACHEBUSTER is the same miss as a display impression that never unique-counted.