Tracking Audit Methodology — 5-Check Protocol
Why This Exists
Our first pass at auditing client websites produced false negatives — we claimed Sixpenny and Freshly Picked had broken Meta tracking when it was actually working behind cookie consent banners. This methodology prevents that mistake.
The 5-Check Protocol
Every site audit MUST run all 5 checks before making any claim.
Check 1: Network Request Monitoring (Pre-Consent)
Load the page with request interception. Capture all requests to tracking domains. This shows what fires WITHOUT user consent.
async (page) => {
const requests = [];
page.on('request', req => {
const url = req.url();
if (url.match(/google|facebook|tiktok|bing|linkedin|pinterest|snap|analytics|pixel|conversion|gtag|gtm/i)) {
requests.push({ url: url.substring(0, 300), type: req.resourceType() });
}
});
await page.goto(TARGET_URL, { waitUntil: 'networkidle' });
await page.waitForTimeout(5000);
return requests;
}Check 2: Cookie Consent Test
Accept cookies/consent banner, wait 5 seconds, then re-check. Many GDPR-compliant sites block ALL tracking until consent.
// Click Accept/Allow button
const btn = await page.$('button:has-text("Accept")') ||
await page.$('button:has-text("Allow")');
if (btn) await btn.click();
await page.waitForTimeout(5000);
// Re-check: did new pixels load?Critical: If pixels load AFTER consent, they are WORKING — not broken. Do not claim otherwise.
Check 3: JavaScript Global State
Check window for tracking functions. Must check BOTH main window AND iframes (Shopify sandboxes).
() => ({
gtag: typeof window.gtag === 'function',
dataLayer: Array.isArray(window.dataLayer),
fbq: typeof window.fbq === 'function',
ttq: !!(window.ttq?.track),
// Shopify Web Pixels run in sandboxed iframes — fbq won't be on main window
shopifyWebPixels: document.querySelectorAll('script[src*="web-pixel"]').length,
})Critical: On Shopify sites, Meta pixel may exist ONLY inside a sandboxed iframe. window.fbq === undefined does NOT mean Meta is missing.
Check 4: Source Code Scan
Scan all <script> tags for pixel IDs and conversion event code:
() => {
const html = document.documentElement.innerHTML;
return {
googleAdsIds: [...new Set(html.match(/AW-\d+/g) || [])],
ga4Ids: [...new Set(html.match(/G-[A-Z0-9]+/g) || [])],
gtmIds: [...new Set(html.match(/GTM-[A-Z0-9]+/g) || [])],
metaPixels: [...new Set(html.match(/fbq\(['"]init['"],\s*['"](\d+)['"]\)/g) || [])],
hasConversionCode: html.includes("gtag('event', 'conversion'") || html.includes("send_to"),
hasFbqTrack: html.includes("fbq('track'"),
hasTtqTrack: html.includes("ttq.track"),
};
}Check 5: Conversion Page Test
Navigate to the site's actual conversion page (form, checkout, thank-you) and check if conversion events fire. This is the definitive test.
// Navigate to conversion-intent page
await page.goto(CONVERSION_URL, { waitUntil: 'networkidle' });
// Look for conversion-specific network requests
// e.g., facebook.com/tr/?ev=Lead, googleadservices.com/pagead/conversionVerdict Framework
| Scenario | Verdict | Safe to Email? |
|---|---|---|
| No pixels at all, no tracking scripts | Confirmed Broken | Yes — provable |
| Pixels loaded, zero conversion events | Confirmed Broken | Yes — provable |
| Pixels blocked pre-consent, work post-consent | Working (consent-gated) | No — this is correct behavior |
| Pixel in Shopify iframe, fires events | Working (sandboxed) | No — modern Shopify approach |
| Pixel ID in console error ("unavailable") | Needs investigation | Check if ID is valid/active |
| PixelYourSite plugin installed, not configured | Confirmed Broken | Yes — provable |
Common False Negatives (Things That Look Broken But Aren't)
window.fbq === undefinedon Shopify — Pixel runs in Shopify Web Pixel sandbox iframe- No tracking pre-consent — GDPR compliance, loads after Accept click
- No
gtag()function — May usedataLayer.push()via GTM instead - No conversion events on homepage — Conversions fire on form/checkout pages only
Common True Positives (Things That Are Actually Broken)
- Zero tracking network requests even AFTER consent — Nothing configured
- Pixel loaded but zero
track/eventcalls in entire source — Install-and-forget - WP Rocket
rocketlazyloadscripttype — Blocks GTM execution - Meta pixel console error "unavailable" — Invalid/deactivated pixel ID
- GCLID hidden fields in forms but no conversion linker — Intended tracking never finished