Repository navigation
Expand file tree
/
Copy pathdocs.html
More file actions
513 lines (449 loc) · 32.3 KB
/
Copy pathdocs.html
File metadata and controls
513 lines (449 loc) · 32.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Marketing Analytics Auditor — Documentation | googleadsagent.ai</title>
<meta name="description" content="Complete documentation for the Marketing Analytics Auditor. Learn how to scan pages for tags, run GA4 audits, analyze pages with AI, and generate remediation code.">
<link rel="canonical" href="https://googleadsagent.ai/tools/auditor/docs.html">
<meta name="robots" content="index, follow">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Courier+Prime:ital@0;1&family=IBM+Plex+Sans:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Playfair+Display:ital,wght@0,400;0,700;1,400&display=swap" rel="stylesheet">
<style>
:root{--bg:#08080d;--bg2:#0e0e16;--bg3:#14141f;--surface:#1a1a2a;--border:#2a2a3a;--text:#e8e6e3;--text2:#9a9aaa;--text3:#6a6a7a;--amber:#f0a830;--green:#4ade80;--blue:#60a5fa;--purple:#a78bfa;--red:#f87171;--cyan:#22d3ee;--font-serif:'Playfair Display',Georgia,serif;--font-mono:'JetBrains Mono','Courier New',monospace;--font-body:'IBM Plex Sans',-apple-system,sans-serif;--font-quote:'Courier Prime','Courier New',monospace}
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--bg);color:var(--text);font-family:var(--font-body);line-height:1.7;-webkit-font-smoothing:antialiased}
a{color:var(--amber);text-decoration:none}a:hover{color:var(--text)}
.layout{display:flex;min-height:100vh}
.sidebar{width:280px;background:var(--bg2);border-right:1px solid var(--border);padding:1.5rem;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:50}
.sidebar-logo{font-family:var(--font-mono);font-size:.8rem;color:var(--text2);margin-bottom:.25rem}
.sidebar-logo span{color:var(--amber)}
.sidebar-title{font-family:var(--font-serif);font-size:1.2rem;font-weight:700;margin-bottom:2rem}
.sidebar-title em{font-style:italic;color:var(--amber)}
.sidebar-section{margin-bottom:1.5rem}
.sidebar-section-title{font-family:var(--font-mono);font-size:.7rem;color:var(--text3);text-transform:uppercase;letter-spacing:.1em;margin-bottom:.5rem}
.sidebar-link{display:block;padding:.35rem .75rem;margin:.15rem 0;border-radius:6px;font-size:.85rem;color:var(--text2);transition:all .2s}
.sidebar-link:hover{background:var(--surface);color:var(--text)}
.sidebar-link.active{background:var(--surface);color:var(--amber)}
.sidebar-divider{border:none;border-top:1px solid var(--border);margin:1rem 0}
.sidebar-actions{display:flex;flex-direction:column;gap:.5rem;margin-top:1rem}
.sidebar-btn{display:inline-flex;align-items:center;justify-content:center;gap:.4rem;padding:.5rem 1rem;border-radius:6px;font-size:.82rem;font-weight:600;text-align:center}
.sidebar-btn.primary{background:var(--amber);color:var(--bg)}
.sidebar-btn.secondary{border:1px solid var(--border);color:var(--text2)}
.sidebar-btn:hover{opacity:.85}
.sidebar-toggle{display:none;position:fixed;top:12px;left:12px;z-index:60;background:var(--bg2);border:1px solid var(--border);border-radius:6px;padding:8px 12px;font-size:14px;color:var(--text2);cursor:pointer}
.main{margin-left:280px;flex:1;max-width:760px;padding:3rem 3rem 6rem}
h1{font-family:var(--font-serif);font-size:2rem;margin-bottom:.5rem;letter-spacing:.02em}
h1 em{color:var(--amber);font-style:italic}
h2{font-family:var(--font-serif);font-size:1.4rem;margin:2.5rem 0 .75rem;padding-top:1.5rem;border-top:1px solid var(--border)}
h3{font-size:1.05rem;margin:1.5rem 0 .5rem;font-weight:600}
p{color:var(--text2);margin-bottom:1rem}
code{font-family:var(--font-mono);background:var(--bg2);padding:2px 6px;border-radius:4px;font-size:.85em;color:var(--cyan)}
pre{background:var(--bg2);border:1px solid var(--border);border-radius:8px;padding:1.25rem;overflow-x:auto;margin:1rem 0;font-family:var(--font-mono);font-size:.82rem;line-height:1.6;color:var(--green)}
pre code{background:none;padding:0;color:inherit}
.badge{display:inline-block;font-family:var(--font-mono);font-size:.7rem;padding:2px 8px;border-radius:4px;margin-left:6px}
.badge.green{background:#4ade8018;color:var(--green);border:1px solid #4ade8033}
.badge.amber{background:#f0a83018;color:var(--amber);border:1px solid #f0a83033}
.badge.blue{background:#60a5fa18;color:var(--blue);border:1px solid #60a5fa33}
.badge.purple{background:#a78bfa18;color:var(--purple);border:1px solid #a78bfa33}
table{width:100%;border-collapse:collapse;margin:1rem 0;font-size:.85rem}
th{text-align:left;padding:.6rem .8rem;border-bottom:2px solid var(--border);color:var(--text);font-weight:600}
td{padding:.6rem .8rem;border-bottom:1px solid var(--border);color:var(--text2)}
tr:last-child td{border-bottom:none}
ul,ol{margin:.5rem 0 1rem 1.5rem;color:var(--text2)}li{margin-bottom:.4rem}
.callout{background:var(--bg2);border:1px solid var(--border);border-radius:8px;padding:1.25rem;margin:1rem 0;font-size:.9rem}
.callout.security{border-color:#4ade8033;background:#4ade8008}
.callout.warning{border-color:#f0a83033;background:#f0a83008}
@media(max-width:768px){
.sidebar{transform:translateX(-100%);transition:transform .3s}.sidebar.open{transform:translateX(0)}
.sidebar-toggle{display:block}
.main{margin-left:0;padding:2rem 1.5rem 4rem}
}
</style>
</head>
<body>
<button class="sidebar-toggle" onclick="document.querySelector('.sidebar').classList.toggle('open')">☰ Menu</button>
<div class="layout">
<nav class="sidebar">
<div class="sidebar-logo"><span>googleadsagent</span>.ai</div>
<div class="sidebar-title">Analytics <em>Auditor</em></div>
<div class="sidebar-section">
<div class="sidebar-section-title">Getting Started</div>
<a href="#overview" class="sidebar-link active">Overview</a>
<a href="#quickstart" class="sidebar-link">Quick Start</a>
<a href="#security" class="sidebar-link">Security & Privacy</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Page Scanner</div>
<a href="#scan-url" class="sidebar-link">Scan a URL</a>
<a href="#scan-html" class="sidebar-link">Paste HTML</a>
<a href="#deep-scan" class="sidebar-link">Deep Scan (Playwright)</a>
<a href="#demo-mode" class="sidebar-link">Demo Mode</a>
<a href="#detected-tags" class="sidebar-link">Tag Detection (10 Platforms)</a>
<a href="#pixel-health" class="sidebar-link">Pixel Health Scores</a>
<a href="#social-meta" class="sidebar-link">Social Meta (OG / Twitter)</a>
<a href="#seo-health" class="sidebar-link">SEO Health</a>
<a href="#schema" class="sidebar-link">Schema / Structured Data</a>
<a href="#ecommerce" class="sidebar-link">Ecommerce Funnel (9 Stages)</a>
<a href="#performance" class="sidebar-link">Performance Signals</a>
<a href="#scoring" class="sidebar-link">Scoring System</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">GA4 Property Audit</div>
<a href="#ga4-setup" class="sidebar-link">Setup (OAuth Playground)</a>
<a href="#ga4-checks" class="sidebar-link">40-Point Checklist</a>
<a href="#ga4-scoring" class="sidebar-link">Grading Scale</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">GTM Container Audit</div>
<a href="#gtm-setup" class="sidebar-link">Setup (OAuth Playground)</a>
<a href="#gtm-checks" class="sidebar-link">Tag / Trigger / Variable Audit</a>
<a href="#gtm-json" class="sidebar-link">GTM Container JSON Export</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">AI Vision</div>
<a href="#vision-setup" class="sidebar-link">Gemini API Key Setup</a>
<a href="#vision-how" class="sidebar-link">How It Works</a>
<a href="#vision-output" class="sidebar-link">Output & Events</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Remediation</div>
<a href="#remediation" class="sidebar-link">Code Generation</a>
<a href="#gtm-import" class="sidebar-link">GTM Import JSON</a>
<a href="#platforms" class="sidebar-link">Supported Platforms</a>
<a href="#exports" class="sidebar-link">Export Formats</a>
<a href="#dev-handoff" class="sidebar-link">Developer Handoff</a>
</div>
<div class="sidebar-section">
<div class="sidebar-section-title">Reference</div>
<a href="#session" class="sidebar-link">Session Storage</a>
<a href="#playwright" class="sidebar-link">Playwright Setup</a>
<a href="#api" class="sidebar-link">API Reference</a>
</div>
<hr class="sidebar-divider">
<div class="sidebar-actions">
<a href="app.html" class="sidebar-btn primary">⚡ Launch Auditor</a>
<a href="https://github.com/itallstartedwithaidea/analytics-auditor" class="sidebar-btn secondary" target="_blank">View Source</a>
<a href="index.html" class="sidebar-btn secondary">← Back to Overview</a>
</div>
</nav>
<main class="main">
<!-- OVERVIEW -->
<h1 id="overview">Analytics <em>Auditor</em> Docs</h1>
<p>The Marketing Analytics Auditor is a free, open-source tool that scans websites for GA4, GTM, and marketing pixel configurations, runs a 40-point GA4 property audit via the Admin API, uses AI to discover untracked page elements, and generates the exact remediation code to fix every issue found.</p>
<div class="callout">
<strong>All features are live:</strong> Page Scanner, GA4 Property Audit (40-point checklist), AI Page Vision (Gemini), and Remediation Code Generation are all available now. <a href="app.html">Launch the Auditor →</a>
</div>
<!-- QUICK START -->
<h2 id="quickstart">Quick Start</h2>
<h3>Page Scanner (zero setup)</h3>
<p>No API keys, no login, no installation. Enter any URL or paste HTML source code and get an instant tag inventory, health score, and remediation code.</p>
<ol>
<li>Go to <a href="app.html">the Auditor app</a></li>
<li>Enter a URL or switch to "Paste HTML"</li>
<li>Review your tag inventory, score, and issues</li>
<li>Click "Show remediation code" on any issue for copy-paste fix code</li>
</ol>
<h3>GA4 Property Audit (needs Google OAuth token)</h3>
<ol>
<li>Open the <strong>GA4 Audit</strong> tab in the Auditor</li>
<li>Follow the OAuth Playground instructions to get a read-only access token (60 seconds)</li>
<li>Paste the token and select your property</li>
<li>Click "Run 40-Point Audit" — results in ~5 seconds</li>
</ol>
<h3>AI Vision (needs free Gemini API key)</h3>
<ol>
<li>Open the <strong>AI Vision</strong> tab</li>
<li>Get a free API key from <a href="https://aistudio.google.com/apikey" target="_blank">Google AI Studio</a></li>
<li>Enter a URL and click "Analyze with AI"</li>
<li>Review the suggested tracking events mapped to GA4 event names</li>
</ol>
<!-- SECURITY -->
<h2 id="security">Security & Privacy</h2>
<div class="callout security">
<strong>🔒 Your data never leaves your browser.</strong> All page analysis runs client-side in JavaScript. No HTML content, URLs, API keys, or scan results are sent to any server we control. API calls go directly from your browser to Google's APIs. We are never a middleman.
</div>
<h3>How credentials are handled</h3>
<table>
<tr><th>Feature</th><th>Keys Required</th><th>Storage</th></tr>
<tr><td>Page Scanner</td><td>None</td><td>N/A — no auth needed</td></tr>
<tr><td>GA4 Audit</td><td>Google OAuth access token</td><td><code>sessionStorage</code> only. Cleared on tab close. Never persisted.</td></tr>
<tr><td>AI Vision</td><td>Gemini API key</td><td><code>sessionStorage</code> only. Never sent to our servers.</td></tr>
</table>
<h3>Security principles</h3>
<ul>
<li><strong>Zero server-side storage.</strong> No database, no user accounts, no cookies from us.</li>
<li><strong>Keys in sessionStorage only.</strong> Cleared when the browser tab closes. Never written to localStorage or sent to any backend.</li>
<li><strong>Read-only API access.</strong> GA4 audit uses <code>analytics.readonly</code> scope — it cannot modify your property.</li>
<li><strong>Direct API calls.</strong> When you connect to GA4 Admin API or Gemini, calls go directly from your browser to Google. We are never in the middle.</li>
<li><strong>Open source.</strong> Every line of code is auditable on <a href="https://github.com/itallstartedwithaidea/analytics-auditor">GitHub</a>. No obfuscation, no telemetry, no analytics.</li>
<li><strong>No third-party scripts.</strong> No Google Analytics, no Meta Pixel, no tracking on the tool itself. Google Fonts is the only external resource.</li>
</ul>
<!-- SCAN URL -->
<h2 id="scan-url">Scan a URL</h2>
<p>Enter any publicly accessible URL. The scanner fetches the page HTML via CORS proxy and analyzes it for marketing tags. The tool tries multiple proxy services automatically — if one fails, it falls back to the next.</p>
<div class="callout warning">
<strong>Limitations of URL scanning:</strong> CORS proxies fetch the initial HTML response only. Tags injected by JavaScript after page load (common with SPAs and React/Next.js sites) may not be detected. For these sites, use "Paste HTML" instead — it captures the full rendered DOM.
</div>
<p>The scanner checks for tags using four methods:</p>
<ul>
<li><strong>DOM script tags</strong> — Pattern matching on <code><script></code> src attributes and inline code</li>
<li><strong>JavaScript globals</strong> — Detection of window objects like <code>fbq</code>, <code>ttq</code>, <code>gtag</code>, <code>dataLayer</code></li>
<li><strong>Network patterns</strong> — URLs referencing known analytics endpoints</li>
<li><strong>Cookie signatures</strong> — Known cookie names like <code>_ga</code>, <code>_fbp</code>, <code>_ttp</code></li>
</ul>
<!-- SCAN HTML -->
<h2 id="scan-html">Paste HTML</h2>
<p>For the most accurate results, paste the page source directly:</p>
<ol>
<li>Open the target page in your browser</li>
<li>Right-click → View Page Source (or Ctrl+U / Cmd+U)</li>
<li>Select all (Ctrl+A) and copy (Ctrl+C)</li>
<li>Switch to the "Paste HTML" tab in the auditor</li>
<li>Paste and click "Analyze HTML"</li>
</ol>
<p>For JavaScript-rendered tags (SPAs), use browser DevTools: Elements tab → right-click the <code><html></code> element → Copy → Copy outerHTML. This captures the fully rendered DOM including dynamically injected scripts.</p>
<!-- DEMO -->
<h2 id="demo-mode">Demo Mode</h2>
<p>Demo mode simulates scanning <code>https://acme-ecommerce.com</code>, a fictional ecommerce site with GA4 via GTM, Meta Pixel with partial Advanced Matching, Google Ads conversion tracking, TikTok base pixel without events, and missing LinkedIn Insight tag. It generates realistic issues and remediation code so you can explore the full experience before scanning a real site.</p>
<!-- DETECTED TAGS -->
<h2 id="detected-tags">Tag Detection</h2>
<p>The scanner detects 10 marketing platforms and validates their configuration:</p>
<table>
<tr><th>Platform</th><th>What's Detected</th><th>What's Validated</th></tr>
<tr><td>Google Analytics 4</td><td>Measurement ID (G-XXXXX), gtag.js or GTM loading</td><td>Enhanced Measurement, dataLayer events, ecommerce events</td></tr>
<tr><td>Google Tag Manager</td><td>Container ID (GTM-XXXXX), dataLayer initialization</td><td>Noscript fallback, dataLayer init before GTM</td></tr>
<tr><td>Meta Pixel</td><td>Pixel ID, fbevents.js loading</td><td>PageView event, Advanced Matching, standard events, CAPI indicators</td></tr>
<tr><td>Google Ads</td><td>Conversion ID (AW-XXXXX)</td><td>Conversion actions, Enhanced Conversions</td></tr>
<tr><td>TikTok Pixel</td><td>Pixel ID, events.js loading</td><td>Standard events (AddToCart, Purchase, SubmitForm)</td></tr>
<tr><td>LinkedIn Insight</td><td>Partner ID, insight.min.js</td><td>Presence detection</td></tr>
<tr><td>Pinterest Tag</td><td>Tag ID, pintrk loading</td><td>Presence detection</td></tr>
<tr><td>Snapchat Pixel</td><td>Pixel ID, scevent.min.js</td><td>Presence detection</td></tr>
<tr><td>X / Twitter Pixel</td><td>Pixel ID, uwt.js loading</td><td>Presence detection</td></tr>
<tr><td>Microsoft UET</td><td>Tag ID, bat.js loading</td><td>Presence detection</td></tr>
</table>
<p>Additionally detects consent management: Google Consent Mode v2, IAB TCF 2.0, and common platforms (OneTrust, Cookiebot, etc.).</p>
<!-- SCORING -->
<h2 id="scoring">Scoring System</h2>
<p>Each scan produces a <strong>Tag Health Score</strong> from 0–100 based on detected issues:</p>
<table>
<tr><th>Severity</th><th>Point Deduction</th><th>Example</th></tr>
<tr><td><span class="badge" style="background:#f8717118;color:var(--red);border:1px solid #f8717133">CRITICAL</span></td><td>-15 points</td><td>No purchase event on ecommerce site</td></tr>
<tr><td><span class="badge" style="background:#f0a83018;color:var(--amber);border:1px solid #f0a83033">HIGH</span></td><td>-10 points</td><td>Meta Advanced Matching missing, TikTok no standard events</td></tr>
<tr><td><span class="badge" style="background:#60a5fa18;color:var(--blue);border:1px solid #60a5fa33">MEDIUM</span></td><td>-5 points</td><td>CAPI not detected, no consent management, dataLayer not initialized</td></tr>
<tr><td><span class="badge" style="background:#a78bfa18;color:var(--purple);border:1px solid #a78bfa33">LOW</span></td><td>-2 points</td><td>GTM noscript fallback missing</td></tr>
</table>
<table>
<tr><th>Score</th><th>Grade</th><th>Meaning</th></tr>
<tr><td>90–100</td><td><span style="color:var(--green)">A — Excellent</span></td><td>Tags well configured, minor optimizations only</td></tr>
<tr><td>80–89</td><td><span style="color:var(--blue)">B — Good</span></td><td>Solid setup with a few recommended improvements</td></tr>
<tr><td>70–79</td><td><span style="color:var(--amber)">C — Needs Attention</span></td><td>Notable gaps in tracking or configuration</td></tr>
<tr><td>60–69</td><td><span style="color:var(--red)">D — Significant Issues</span></td><td>Missing critical tracking — data quality impacted</td></tr>
<tr><td>0–59</td><td><span style="color:var(--red)">F — Critical</span></td><td>Fundamental tracking problems — data likely unreliable</td></tr>
</table>
<!-- GA4 SETUP -->
<h2 id="ga4-setup">GA4 Audit: Setup (OAuth Playground)</h2>
<p><span class="badge green">LIVE</span> Connect your Google account to run a full 40-point GA4 property audit via the Admin API. The entire process takes about 60 seconds.</p>
<h3>Step-by-step</h3>
<ol>
<li>Open the <strong>GA4 Audit</strong> tab in the Auditor app</li>
<li>Click the link to <a href="https://developers.google.com/oauthplayground/" target="_blank">Google OAuth Playground</a></li>
<li>In <strong>Step 1</strong>, scroll to <strong>Google Analytics Admin API v1beta</strong> and select:<br><code>https://www.googleapis.com/auth/analytics.readonly</code></li>
<li>Click <strong>Authorize APIs</strong> — sign in with the Google account that has access to your GA4 property</li>
<li>In <strong>Step 2</strong>, click <strong>Exchange authorization code for tokens</strong></li>
<li>Copy the <strong>Access token</strong> value (starts with <code>ya29.</code>)</li>
<li>Paste it into the Auditor's token field and click <strong>Save & Load Properties</strong></li>
<li>Select your property from the dropdown and click <strong>Run 40-Point Audit</strong></li>
</ol>
<div class="callout warning">
<strong>Token expires in ~1 hour.</strong> If you get a 401 error, return to OAuth Playground and generate a new token. The token grants <strong>read-only</strong> access — it cannot modify your GA4 property settings.
</div>
<h3>Required scope</h3>
<pre><code>https://www.googleapis.com/auth/analytics.readonly</code></pre>
<p>This scope provides read-only access to property settings, data streams, enhanced measurement configuration, key events, product links, custom dimensions, audiences, and attribution settings. It cannot create, modify, or delete anything.</p>
<!-- GA4 CHECKS -->
<h2 id="ga4-checks">GA4: 40-Point Checklist</h2>
<p><span class="badge green">LIVE</span> The audit queries the GA4 Admin API and checks 7 categories:</p>
<table>
<tr><th>Category</th><th>Checks</th><th>Key Items</th></tr>
<tr><td>Property Configuration</td><td>7+</td><td>Timezone, currency, industry category, data retention (14mo vs 2mo), attribution model, reporting attribution</td></tr>
<tr><td>Data Streams</td><td>2+</td><td>Web stream exists, measurement ID valid and active</td></tr>
<tr><td>Enhanced Measurement</td><td>8</td><td>Master toggle, page views, scrolls, outbound clicks, site search, video engagement, file downloads, form interactions</td></tr>
<tr><td>Key Events</td><td>3+</td><td>At least 1 key event defined, industry-appropriate events (purchase or generate_lead), counting method</td></tr>
<tr><td>Product Links</td><td>1+</td><td>Google Ads linked</td></tr>
<tr><td>Custom Definitions</td><td>2+</td><td>Custom dimensions defined, naming conventions (snake_case, no spaces)</td></tr>
<tr><td>Audiences</td><td>1+</td><td>Audiences beyond defaults (All Users + Purchasers)</td></tr>
</table>
<p>Each check returns <span style="color:var(--green)">✓ Pass</span>, <span style="color:var(--amber)">⚠ Warning</span>, <span style="color:var(--red)">✗ Fail</span>, or <span style="color:var(--text3)">— N/A</span>. The overall score starts at 100 and deducts 10 for failures and 3 for warnings.</p>
<!-- GA4 SCORING -->
<h2 id="ga4-scoring">GA4 Audit Grading</h2>
<p>The GA4 audit uses the same A–F grading scale as the page scanner. Common issues that drop scores:</p>
<ul>
<li><strong>Data retention set to 2 months</strong> (default) — should be 14 months</li>
<li><strong>No key events defined</strong> — GA4 is collecting data but not measuring conversions</li>
<li><strong>Enhanced measurement toggles off</strong> — missing scroll, video, file download tracking</li>
<li><strong>Google Ads not linked</strong> — conversion data not flowing to ad campaigns</li>
<li><strong>No custom dimensions</strong> — missing user segmentation capability</li>
<li><strong>Only default audiences</strong> — no retargeting audiences built</li>
</ul>
<!-- AI VISION SETUP -->
<h2 id="vision-setup">AI Vision: Gemini API Key Setup</h2>
<p><span class="badge green">LIVE</span> The AI Vision feature uses Google's Gemini 2.0 Flash model to analyze webpage HTML and identify every trackable interactive element.</p>
<h3>Get your free Gemini API key</h3>
<ol>
<li>Go to <a href="https://aistudio.google.com/apikey" target="_blank">Google AI Studio</a></li>
<li>Sign in with any Google account</li>
<li>Click <strong>Create API key</strong></li>
<li>Copy the key and paste it into the Auditor's <strong>AI Vision</strong> tab</li>
</ol>
<div class="callout security">
<strong>🔒 Your API key never touches our servers.</strong> The call goes directly from your browser to <code>generativelanguage.googleapis.com</code>. We never see your key. It's stored in <code>sessionStorage</code> only — gone when you close the tab.
</div>
<p>The free tier of Gemini API provides generous usage limits for individual audits. No billing setup is required.</p>
<!-- AI VISION HOW -->
<h2 id="vision-how">AI Vision: How It Works</h2>
<p>When you run an AI Vision scan:</p>
<ol>
<li>The tool fetches the page HTML via CORS proxy (same as Page Scanner)</li>
<li>The HTML (truncated to fit context) is sent to Gemini 2.0 Flash with a specialized analytics prompt</li>
<li>The AI identifies every interactive element on the page that should be tracked</li>
<li>Results are returned as structured data with GA4 event recommendations</li>
</ol>
<p>The AI looks for 6 categories of trackable elements:</p>
<ul>
<li><strong>Forms</strong> — Contact forms, signup forms, newsletter opt-ins, search boxes</li>
<li><strong>CTAs</strong> — Buttons and links that are calls-to-action (Buy Now, Get Started, etc.)</li>
<li><strong>Navigation</strong> — Menu items, category links, filter controls</li>
<li><strong>Ecommerce</strong> — Product cards, add-to-cart buttons, wishlist, cart icon</li>
<li><strong>Engagement</strong> — Video players, image carousels, tabs, accordions, chat widgets</li>
<li><strong>Conversion</strong> — Phone numbers, email links, booking/scheduling widgets</li>
</ul>
<!-- AI VISION OUTPUT -->
<h2 id="vision-output">AI Vision: Output</h2>
<p>For each element the AI finds, you get:</p>
<table>
<tr><th>Field</th><th>Description</th></tr>
<tr><td><strong>Event name</strong></td><td>Recommended GA4 event name in <code>snake_case</code> (e.g., <code>generate_lead</code>, <code>view_item</code>)</td></tr>
<tr><td><strong>Element</strong></td><td>Description of the interactive element and its location</td></tr>
<tr><td><strong>Parameters</strong></td><td>Key parameters to capture (e.g., <code>form_name</code>, <code>button_text</code>, <code>video_title</code>)</td></tr>
<tr><td><strong>Priority</strong></td><td>Critical, High, Medium, or Low</td></tr>
<tr><td><strong>Tracked</strong></td><td>Yes, Partial, or No — based on what the AI sees in the existing HTML</td></tr>
</table>
<p>If you've already run a Page Scan, the AI Vision results complement it by finding elements that the DOM-based scanner can't detect (interactive behaviors, visual CTAs, etc.).</p>
<!-- REMEDIATION -->
<h2 id="remediation">Remediation Code Generation</h2>
<p><span class="badge green">LIVE</span> For every issue found by the Page Scanner, the tool generates platform-specific, copy-paste-ready code. This is the core differentiator — no other tool does this.</p>
<h3>Types of generated code</h3>
<table>
<tr><th>Issue Type</th><th>Generated Fix</th></tr>
<tr><td>Missing ecommerce events</td><td><code>dataLayer.push()</code> for <code>purchase</code>, <code>add_to_cart</code>, <code>view_item</code>, <code>begin_checkout</code></td></tr>
<tr><td>Missing lead events</td><td><code>dataLayer.push()</code> for <code>generate_lead</code> with form parameters</td></tr>
<tr><td>Missing pixel events</td><td>Platform-specific event code (<code>fbq</code>, <code>ttq</code>, etc.) with required parameters</td></tr>
<tr><td>Missing pixels entirely</td><td>Full base code installation snippet (e.g., LinkedIn Insight tag)</td></tr>
<tr><td>Meta CAPI not detected</td><td>Server-side endpoint boilerplate in Node.js with Python guidance</td></tr>
<tr><td>Missing consent</td><td>Google Consent Mode v2 default + update template</td></tr>
<tr><td>Missing Enhanced Conversions</td><td><code>gtag('set', 'user_data', {...})</code> with all supported fields</td></tr>
<tr><td>dataLayer not initialized</td><td><code>window.dataLayer = window.dataLayer || []</code> with initial page data push</td></tr>
<tr><td>GTM noscript missing</td><td>Complete <code><noscript></code> iframe snippet</td></tr>
</table>
<h3>Using remediation code</h3>
<ol>
<li>Click <strong>"Show remediation code"</strong> on any issue</li>
<li>Click <strong>"Copy"</strong> to copy to clipboard</li>
<li>Replace <code>{{PLACEHOLDER}}</code> values with your actual dynamic values (e.g., <code>{{ORDER_ID}}</code>, <code>{{PIXEL_ID}}</code>)</li>
<li>Deploy via GTM custom HTML tag, or paste directly into your page template</li>
<li>Test using GTM Preview Mode, Meta Pixel Helper, or browser DevTools console</li>
</ol>
<!-- PLATFORMS -->
<h2 id="platforms">Supported Platforms</h2>
<table>
<tr><th>Platform</th><th>Detection</th><th>Validation</th><th>Remediation Code</th></tr>
<tr><td>Google Analytics 4</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td></tr>
<tr><td>Google Tag Manager</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td></tr>
<tr><td>Meta Pixel</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td></tr>
<tr><td>Google Ads</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td></tr>
<tr><td>TikTok Pixel</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td><td style="color:var(--green)">✓</td></tr>
<tr><td>LinkedIn Insight</td><td style="color:var(--green)">✓</td><td>—</td><td style="color:var(--green)">✓</td></tr>
<tr><td>Pinterest Tag</td><td style="color:var(--green)">✓</td><td>—</td><td>—</td></tr>
<tr><td>Snapchat Pixel</td><td style="color:var(--green)">✓</td><td>—</td><td>—</td></tr>
<tr><td>X / Twitter Pixel</td><td style="color:var(--green)">✓</td><td>—</td><td>—</td></tr>
<tr><td>Microsoft UET</td><td style="color:var(--green)">✓</td><td>—</td><td>—</td></tr>
</table>
<!-- EXPORTS -->
<h2 id="exports">Export Formats</h2>
<table>
<tr><th>Format</th><th>Contents</th><th>Best For</th></tr>
<tr><td>JSON</td><td>Complete scan results with all metadata</td><td>Programmatic use, CI/CD integration</td></tr>
<tr><td>CSV</td><td>Tag inventory with status and issues</td><td>Spreadsheet analysis, client reporting</td></tr>
<tr><td>Remediation TXT</td><td>All fix code with descriptions, severity-ordered</td><td>Developer handoff</td></tr>
<tr><td>Print / PDF</td><td>Full visual report</td><td>Client presentations, audit documentation</td></tr>
</table>
<!-- SESSION -->
<h2 id="session">Session Storage</h2>
<p>The Auditor uses <code>sessionStorage</code> to keep your credentials and scan results available for the duration of your browser session.</p>
<h3>What's stored</h3>
<table>
<tr><th>Key</th><th>Value</th><th>Lifetime</th></tr>
<tr><td><code>ga4_token</code></td><td>Google OAuth access token</td><td>Until tab closes or token expires (~1 hour)</td></tr>
<tr><td><code>gemini_key</code></td><td>Gemini API key</td><td>Until tab closes</td></tr>
</table>
<p>Scan results (tags, scores, issues) are held in JavaScript memory only — not written to <code>sessionStorage</code>. They persist as long as you don't refresh the page.</p>
<h3>Clearing your data</h3>
<p>Use the <strong>Settings</strong> tab to view, clear individual keys, or nuke everything with "Clear All Keys & Data." Closing the browser tab also clears everything automatically.</p>
<!-- API -->
<h2 id="api">API Reference</h2>
<p>The scan engine is a set of JavaScript functions embedded in <code>app.html</code>. Key functions available in the global scope:</p>
<pre><code>// Run a scan on HTML string
var result = scanHTML(htmlString, 'https://example.com');
// Result structure:
{
url: string,
scannedAt: string, // ISO 8601
tags: { [key]: TagResult },
consent: ConsentResult,
issues: Issue[],
score: number, // 0-100
grade: string, // A-F
gradeLabel: string,
tagCount: number,
issueCount: number
}
// Each issue:
{
sev: 'critical' | 'high' | 'medium' | 'low',
title: string,
desc: string,
fix: string // Copy-paste remediation code
}</code></pre>
<p>For integration into other tools, the <code>TAG_DEFS</code> object contains all platform detection signatures and can be extended with new platforms. See <a href="https://github.com/itallstartedwithaidea/analytics-auditor/blob/main/CONTRIBUTING.md">CONTRIBUTING.md</a> for instructions.</p>
<hr style="border:none;border-top:1px solid var(--border);margin:3rem 0 2rem">
<p style="font-size:.82rem;color:var(--text3)">
Built by <a href="https://itallstartedwithaidea.com">John Williams</a> — Senior Paid Media Specialist at <a href="https://www.seerinteractive.com">Seer Interactive</a>.<br>
Part of the <a href="https://googleadsagent.ai">Google Ads Agent</a> ecosystem. <a href="https://github.com/itallstartedwithaidea/analytics-auditor">Open source on GitHub.</a>
</p>
</main>
</div>
<script>
(function(){
var links = document.querySelectorAll('.sidebar-link');
var sections = [];
links.forEach(function(l){
var id = l.getAttribute('href');
if(id && id.startsWith('#')){
var el = document.querySelector(id);
if(el) sections.push({el:el, link:l});
}
});
window.addEventListener('scroll', function(){
var top = window.scrollY + 100;
var active = sections[0];
sections.forEach(function(s){ if(s.el.offsetTop <= top) active = s; });
links.forEach(function(l){ l.classList.remove('active'); });
if(active) active.link.classList.add('active');
});
})();
</script>
</body>
</html>