1<!DOCTYPE html><html lang="en"><head>
1<script>(function(w,i,g){w[g]=w[g]||[];if(typeof w[g].push=='function')w[g].push(i)}) 2(window,'GTM-PH3XWHJ5','google_tags_first_party');</script>
2<script>(function(w,d,s,l){w[l]=w[l]||[];(function(){w[l].push(arguments);})('set', 'developer_id.dYzg1YT', true); 3 w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], 4 j=d.createElement(s);j.async=true;j.src='/2j52/'; 5 f.parentNode.insertBefore(j,f); 6 })(window,document,'script','dataLayer');</script>
6 7 <!-- Pre-rendered by build-pages.ts --> 8 <link rel="canonical" href="https://app.getcitable.com/signin"> 9 <!-- 10 Asset recovery â for the entry module and the stylesheet. 11 12 If an /assets/ chunk fails to load, nothing in the app can help: no app 13 code has run, so lib/vite-chunk-reload.ts is not installed. And the page 14 still LOOKS like a page, because build-pages.ts prerendered it. 15 16 That is what happened on 2026-08-10, twice over. A propagation gap made 17 the SPA catch-all answer the entry chunk with index.html, and Cloudflare 18 cached that HTML under the asset URL as `immutable, max-age=31536000` â 19 and, because the tags below are `crossorigin`, under the CORS cache 20 variant specifically. So `curl` got clean JS and every browser got HTML. 21 Nothing we had could see it: CI, the deploy, and verify-spa-assets.sh 22 were all green while the site was dark for every visitor at that edge. 23 24 On 2026-08-13 the same mechanism hit the STYLESHEET, and it presents 25 completely differently: React mounts, the API answers, the charts draw â 26 and the whole product paints in serif Times with no layout. It is fully 27 functional and reads as totally broken. `nosniff` on /assets/* is what 28 makes it recoverable at all: the browser refuses the mislabeled sheet 29 instead of rendering it, and fires `error` at the link, which is the hook 30 below. Note that clearing the browser cache does NOT fix this â the 31 poisoned object is at the visitor's Cloudflare PoP, not on their machine. 32 33 Reloading cannot fix it either: while `immutable` was set, browsers would 34 not revalidate even on a hard reload, and even now a reload just re-reads 35 the same poisoned object from the same edge. The only way out is a URL 36 the cache has never seen, which is what this does: on the error event, 37 re-inject the asset once with a cache-busting query. Different URL, 38 different cache key, fresh fetch â and the user never knows. 39 40 Notes: 41 - Capture phase: resource load errors do not bubble. 42 - No `crossorigin` on the retry, deliberately. Without it the request 43 is same-origin mode and sends no Origin header, so it cannot land on 44 the CORS variant that was poisoned in the first place. 45 - The stylesheet retry goes directly after the sheet it replaces, so 46 cascade order is unchanged. 47 - One shot per URL. A URL carrying `cb=` is never re-retried at the 48 asset level â but a failed retry is not ignored either, because it 49 means something worse than poisoning (below). 50 - `modulepreload` is skipped â it is only a hint, and the real module 51 tag reports its own error. 52 53 THE LAST RESORT â when the retry itself fails (2026-08-18, Misshow). 54 55 A cache-busted retry failing means the asset is not poisoned at one 56 cache key, it is GONE: this page is stale HTML naming an entry chunk 57 that no deployment serves anymore. Every /assets/ answer for it is the 58 SPA shell (or a 404), so no asset-level retry can ever succeed. A client 59 spent two days on a pixel-perfect /signin where both buttons were dead â 60 her browser held old HTML through ~40 deploys, and a Cloudflare purge 61 cannot reach a client-side cache. Switching browsers "fixed" it, which 62 is the tell: fresh HTML was always the cure. 63 64 So when a retry fails, navigate ONCE to this same page with a 65 `__fresh=` query â a URL no HTML cache has seen, hence a real fetch of 66 current HTML naming a chunk that exists. location.reload() would NOT 67 work here: it revalidates at best, and the caches that cause this 68 (client disk, China-route intermediates) serve the stale copy right 69 back. Three interlocks keep it from ever looping or misfiring: 70 - once per page lifetime (freshTried); 71 - never when `__fresh=` is already in the URL â fresh HTML that still 72 fails means the deploy itself is broken, and a loop is worse; 73 - never after the app has booted (__CITABLE_BOOTED__, set by 74 main.tsx) â a runtime lazy-chunk failure belongs to 75 lib/vite-chunk-reload.ts, and a forced navigation mid-session
75would 76 destroy user state. 77 78 THE THIRD RUNG â a poisoned chunk the entry IMPORTS (2026-09-15, IAD). 79 80 Everything above rescues the tag that errored, which is not the same as 81 rescuing the page. A module's static imports are URLs no retry can reach: 82 `index-*.js?cb=1` still imports `./ui-vendor-*.js` â relative resolution 83 drops the query â and the browser has already memoized that URL's failure 84 for the life of the document. So when the poisoned object was a VENDOR 85 chunk, the whole ladder ran and the page stayed dead: retry, `__fresh=`, 86 the same URLs, the same HTML. Reproduced in a real browser with the old 87 guard as a control: scripts/manual-verify/poisoned-chunk-recovery.mjs. 88 89 That is #1072's deploy. Colo IAD held the shell under BOTH the entry and 90 `ui-vendor-*`; verify-spa-assets.sh passed with a warning promising that 91 visitors there "self-heal via the recovery guard"; the boot check then 92 failed 6 attempts over 300s. The promise was false, and re-running the 93 same commit could not clear it â same hashes, same cache keys. 94 95 A fresh document is the only place this can be fixed. An import map is 96 accepted only before any module has loaded, and it is the one mechanism 97 that can redirect a specifier another module hard-codes. So before the 98 `__fresh=` navigation, stash the /assets/ URLs this document NAMES â the 99 entry plus every modulepreload, which is exactly Vite's static import 100 graph. The next document remaps each to a `?cb=` twin, so the entire 101 graph is fetched under keys no cache has ever seen. 102 103 Notes: 104 - Consumed once, and ignored when older than a minute: a stale stash 105 names hashes a later deploy has already moved past. 106 - The stash is the trigger, not `__fresh=`, so the same handoff serves 107 any ladder that reloads (lib/vite-chunk-reload.ts). 108 - LIMIT: lazily-imported route chunks are not in the map, because the 109 document never names them. A poisoned route chunk stays 110 lib/vite-chunk-reload.ts's problem, not this one. 111 --> 112
112<script> 113 (function () { 114 var STASH = 'citable:asset-bust'; 115 var retried = []; 116 var freshTried = false; 117 118 // Fresh mode. A previous document died on an asset it could not retry 119 // its way out of and left the chunk list behind. Remap every one to a 120 // cache-busting twin NOW, before the parser reaches the module tags: 121 // an import map is only accepted while no module has loaded. 122 try { 123 var stash = sessionStorage.getItem(STASH); 124 if (stash) { 125 sessionStorage.removeItem(STASH); 126 var plan = JSON.parse(stash); 127 var supported = window.HTMLScriptElement 128 && HTMLScriptElement.supports 129 && HTMLScriptElement.supports('importmap'); 130 if (supported && plan && plan.urls && plan.urls.length 131 && Date.now() - plan.t < 60000) { 132 var imports = {}; 133 for (var i = 0; i < plan.urls.length; i++) { 134 imports[plan.urls[i]] = plan.urls[i] + '?cb=' + plan.t; 135 } 136 var map = document.createElement('script'); 137 map.type = 'importmap'; 138 map.textContent = JSON.stringify({ imports: imports }); 139 document.head.appendChild(map); 140 } 141 } 142 } catch (e) { 143 // Storage blocked or the stash was malformed. The rungs below still 144 // work exactly as they did before. 145 } 146 147 /** 148 * Every /assets/ URL this document names: the entry module tag and 149 * Vite's modulepreload links, which together are the chunks the entry 150 * imports statically. Queries are stripped so a `cb=` retry and the 151 * original it replaced collapse to one entry. 152 */ 153 function stashStaticGraph() { 154 try { 155 var urls = []; 156 var nodes = document.querySelectorAll( 157 'link[rel="modulepreload"][href], script[type="module"][src]' 158 ); 159 for (var n = 0; n < nodes.length; n++) { 160 var u = (nodes[n].getAttribute('href') || nodes[n].getAttribute('src') || '').split('?')[0]; 161 if (u.lastIndexOf('/assets/', 0) === 0 && urls.indexOf(u) === -1) urls.push(u); 162 } 163 if (urls.length) { 164 sessionStorage.setItem(STASH, JSON.stringify({ t: Date.now(), urls: urls })); 165 } 166 } catch (e) { 167 // No storage â the next document simply behaves as it used to. 168 } 169 } 170 171 window.addEventListener('error', function (event) { 172 var el = event.target; 173 if (!el) return; 174 175 var isStyle = el.tagName === 'LINK' && el.getAttribute('rel') === 'stylesheet'; 176 if (el.tagName !== 'SCRIPT' && !isStyle) return; 177 178 var url = (isStyle ? el.getAttribute('href') : el.getAttribute('src')) || ''; 179 if (url.lastIndexOf('/assets/', 0) !== 0) return; 180 if (url.indexOf('cb=') !== -1) { 181 // A retry has itself failed â the asset is gone, not poisoned. 182 // Only fresh HTML can name a chunk that exists. See header. 183 if (freshTried) return; 184 if (window.__CITABLE_BOOTED__) return; 185 var loc = window.location; 186 if ((loc.search || '').indexOf('__fresh=') !== -1) return; 187 freshTried = true; 188 stashStaticGraph(); 189 loc.replace( 190 loc.pathname + 191 (loc.search ? loc.search + '&' : '?') + 192 '__fresh=' + Date.now() + 193 (loc.hash || '') 194 ); 195 return; 196 } 197 if (retried.indexOf(url) !== -1) return; 198 retried.push(url); 199 200 var fresh = url + (url.indexOf('?') === -1 ? '?' : '&') + 'cb=' + Date.now(); 201 if (isStyle) { 202 var sheet = document.createElement('link'); 203 sheet.rel = 'stylesheet'; 204 sheet.href = fresh; 205 (el.parentNode || document.head).insertBefore(sheet, el.nextSibling); 206 } else { 207 var script = document.createElement('script'); 208 script.type = 'module';
209 script.src = fresh; 210 document.head.appendChild(script); 211 } 212 }, true); 213 })(); 214 </script>
214 215 216 <!-- Basic Meta Tags (render-critical, must be first) --> 217 <meta charset="UTF-8"> 218 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1"> 219 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 220 221 <!-- SEO Meta Tags --> 222 <title>Citable â The Autonomous Revenue Engine for Agentic Commerce</title> 223 <meta name="description" content="Citable is the autonomous revenue engine for agentic commerce. We measure how AI agents decide what shoppers buy, act on what we find, and prove the results in orders."> 224 <meta name="author" content="Citable"> 225 <meta name="robots" content="index, follow"> 226 227 <!-- Open Graph / Facebook --> 228 <meta property="og:type" content="website"> 229 <meta property="og:url" content="https://getcitable.com/"> 230 <meta property="og:title" content="Citable â The Autonomous Revenue Engine for Agentic Commerce"> 231 <meta property="og:description" content="Citable is the autonomous revenue engine for agentic commerce. We measure how AI agents decide what shoppers buy, act on what we find, and prove the results in orders."> 232 <meta property="og:image" content="https://getcitable.com/og-image-v3.jpg"> 233 <meta property="og:image:width" content="1200"> 234 <meta property="og:image:height" content="628"> 235 <meta property="og:image:type" content="image/jpeg"> 236 <meta property="og:site_name" content="Citable"> 237 238 <!-- Twitter Card --> 239 <meta name="twitter:card" content="summary_large_image"> 240 <meta name="twitter:url" content="https://getcitable.com/"> 241 <meta name="twitter:title" content="Citable â The Autonomous Revenue Engine for Agentic Commerce"> 242 <meta name="twitter:description" content="Citable is the autonomous revenue engine for agentic commerce. We measure how AI agents decide what shoppers buy, act on what we find, and prove the results in orders."> 243 <meta name="twitter:image" content="https://getcitable.com/og-image-v3.jpg"> 244 <meta name="twitter:site" content="@BeCitable"> 245 <meta name="twitter:creator" content="@BeCitable"> 246 247 <!-- Security & Trust Meta Tags --> 248 <meta name="referrer" content="strict-origin-when-cross-origin"> 249 <meta name="format-detection" content="telephone=no"> 250 <meta http-equiv="x-dns-prefetch-control" content="on"> 251 252 <!-- Preload hero image for fast LCP --> 253 <link rel="preload" as="image" href="/Hero-V2-optimized.webp" fetchpriority="high"> 254 255 <!-- Brand fonts are self-hosted via @fontsource (see frontend/src/main.tsx). 256 Eliminates render-blocking Google Fonts roundtrip + CLS from font swap. --> 257 258 <!-- Canonical URL --> 259 <!-- Favicon & App Icons --> 260 <link rel="icon" type="image/png" href="/favicon.png"> 261 <link rel="apple-touch-icon" href="/favicon.png"> 262 263 <!-- Sitemap --> 264 <link rel="sitemap" type="application/xml" href="/sitemap.xml"> 265 266 <!-- Business & Contact Information (Structured Data) --> 267
267<script type="application/ld+json"> 268 { 269 "@context": "https://schema.org", 270 "@type": "SoftwareApplication", 271 "name": "Citable", 272 "applicationCategory": "BusinessApplication", 273 "offers": { 274 "@type": "AggregateOffer", 275 "lowPrice": "99", 276 "highPrice": "799", 277 "priceCurrency": "USD" 278 }, 279 "operatingSystem": "Web", 280 "description": "Citable is the autonomous revenue engine for agentic commerce. We measure how AI agents decide what shoppers buy across ChatGPT, Perplexity, Gemini, Claude, Grok, and Google AI Overview, act on what we find, and prove the results in orders." 281 } 282 </script>
282 283 284 <!-- Organization Schema --> 285
285<script type="application/ld+json"> 286 { 287 "@context": "https://schema.org", 288 "@type": "Organization", 289 "name": "Citable", 290 "url": "https://getcitable.com", 291 "logo": "https://getcitable.com/logo-black.svg", 292 "description": "The autonomous revenue engine for agentic commerce. Founded 2025, Cambridge, Massachusetts.", 293 "foundingDate": "2025", 294 "address": { 295 "@type": "PostalAddress", 296 "addressLocality": "Cambridge", 297 "addressRegion": "MA", 298 "addressCountry": "US" 299 }, 300 "sameAs": [ 301 "https://x.com/BeCitable", 302 "https://www.linkedin.com/company/getcitable", 303 "https://www.youtube.com/@Citable-x5n", 304 "https://www.producthunt.com/products/citable" 305 ], 306 "contactPoint": { 307 "@type": "ContactPoint", 308 "email": "[email protected]", 309 "contactType": "Customer Support", 310 "availableLanguage": "English" 311 } 312 } 313 </script>
313 314
314<script type="module" crossorigin="" src="/assets/index-CV2ezbu5.js"></script>
314 315 <link rel="modulepreload" crossorigin="" href="/assets/react-vendor-Cak5aoPl.js"> 316 <link rel="modulepreload" crossorigin="" href="/assets/utils-vendor-B9hPcH9G.js"> 317 <link rel="modulepreload" crossorigin="" href="/assets/chart-vendor-C3HjQ_mn.js"> 318 <link rel="modulepreload" crossorigin="" href="/assets/ui-vendor-CjS9qaFR.js"> 319 <link rel="modulepreload" crossorigin="" href="/assets/animation-vendor-Cz81Kal9.js"> 320 <link rel="stylesheet" crossorigin="" href="/assets/index-CuYpI8-C.css"> 321 </head> 322 <body> 323 <!-- SEO-friendly content for crawlers (hidden once React loads) --> 324 <noscript> 325 <h1>Citable â The Autonomous Revenue Engine for Agentic Commerce</h1> 326 <p>Citable is the autonomous revenue engine for agentic commerce. We measure how AI agents decide what shoppers buy, act on what we find, and prove the results in orders.</p> 327 </noscript> 328 <div id="root"><div id="toast-dock"><div role="region" aria-label="Notifications (F8)" tabindex="-1" style="pointer-events: none;"><ol tabindex="-1" class="fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]"></ol></div></div><div class="min-h-screen flex flex-col"><main class="flex-1"><div class="min-h-screen flex" style="font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "system-ui", sans-serif;"><div class="flex-1 min-h-screen bg-white flex items-center justify-center px-8 py-12"><div class="w-full max-w-sm"><div class="space-y-6"><div class="text-center mb-10"><img src="/logo-black.svg" alt="Citable" class="w-10 h-10 mx-auto"></div><div class="text-center space-y-1"><h1 class="text-2xl font-semibold text-gray-900 tracking-tight">Welcome back</h1><p class="text-sm text-gray-500">Sign in using Google or email</p></div><div class="space-y-3"><a href="/api/auth/google?returnUrl=%2Fdashboard" class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border bg-background hover:text-gray-900 px-4 py-2 w-full border-gray-300 hover:bg-gray-50 text-gray-700 font-medium rounded-lg transition-all duration-200 h-11"><svg class="w-5 h-5 mr-2" viewBox="0 0 24 24"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"></path><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"></path><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"></path><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"></path></svg>Sign in with Google</a><div class="relative"><div class="absolute inset-0 flex items-center"><span class="w-full border-t border-gray-200"></span></div><div class="relative flex justify-center"><span class="bg-white px-3 text-xs text-gray-400">or</span></div></div><button class="inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 border bg-background hover:text-gray-900 px-4 py-2 w-full border-gray-300 hover:bg-gray-50 text-gray-700 font-medium rounded-lg transition-all duration-200 h-11" type="button"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail w-5 h-5 mr-2 text-gray-500"><rect width="20" height="16" x="2" y="4" rx="2"></rect><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"></path></svg>Sign in with email</button><div class="text-center pt-1"><p class="text-sm text-gray-600">Don't have an account? <button type="button" class="text-gray-900 underline font-normal hover:text-gray-700 transition-colors">Sign up</button></p></div></div></div></div></div><div class="hidden lg:block w-px bg-gray-200"></div><div class="hidden lg:flex flex-col w-1/2 min-h-screen px-10 py-10" style="background-color: rgb(242, 241, 237);"><div class="flex-1 flex flex-col justify-center gap-6"><div class="w-full flex flex-col gap-3"><div class="relative overflow-hidden rounded-2xl shadow-md bg-white" style="cursor: grab;"><div class="flex" draggable="false" style="width: 2240px; user-select: none; touch-action: pan-y; transform: none;"><div style="width: 560px; flex-shrink: 0;"><img src="/%5BInside%20Citable%5D%20Blog%20Generator.png" alt="Publish AI-cited blog posts that get found by ChatGPT & Perplexity" class="w-full h-auto block select-none" draggable="false"></div><div style="width: 560px; flex-shrink: 0;"><img src="/%5BInside%20Citable%5D%20Reddit%20Growth%20Assistant.png" alt="Grow your Reddit presence authentically â without risking a ban" class="w-full h-auto block select-none" draggable="false"></div><div style="width: 560px; flex-shrink: 0;"><img src="/%5BInside%20Citable%5D%20Youtube%20Video%20Generator.png" alt="Go from brand idea to published YouTube video in under a minute" class="w-full h-auto block select-none" draggable="false"></div><div style="width: 560px; flex-shrink: 0;"><img src="/%5BInside%20Citable%5D%20AI%20Action%20Engine.png" alt="Your personal AI growth expert that takes action â so you don't have to" class="w-full h-auto block select-none" draggable="false"></div></div></div><div class="flex justify-center items-center gap-2"><button aria-label="Go to slide 1" class="h-1.5 rounded-full transition-all duration-300 focus:outline-none" style="width: 28px; background-color: rgb(31, 41, 55);"></button><button aria-label="Go to slide 2" class="h-1.5 rounded-full transition-all duration-300 focus:outline-none" style="width: 8px; background-color: rgb(200, 199, 195);"></button><button aria-label="Go to slide 3" class="h-1.5 rounded-full transition-all duration-300 focus:outline-none" style="width: 8px; background-color: rgb(200, 199, 195);"></button><button aria-label="Go to slide 4" class="h-1.5 rounded-full transition-all duration-300 focus:outline-none" style="width: 8px; background-color: rgb(200, 199, 195);"></button></div><p class="text-center text-xs text-gray-500 leading-snug px-2">Publish AI-cited blog posts that get found by ChatGPT & Perplexity</p><div class="grid grid-cols-4 gap-3 mt-1"><button class="rounded-xl p-3 flex flex-col gap-1 text-left transition-all duration-200 focus:outline-none" style="background-color: rgb(232, 231, 227);"><p class="text-12 font-semibold tracking-widest uppercase leading-tight text-gray-400">AI VISIBILITY UPLIFT</p><p class="text-lg font-bold leading-tight transition-colors duration-300" style="color: rgb(90, 143, 114);">0% â 8%</p></button><button class="rounded-xl p-3 flex flex-col gap-1 text-left transition-all duration-200 focus:outline-none" style="background-color: rgb(232, 231, 227);"><p class="text-12 font-semibold tracking-widest uppercase leading-tight text-gray-400">RANKING</p><p class="text-lg font-bold leading-tight transition-colors duration-300" style="color: rgb(31, 41, 55);">#1</p></button><button class="rounded-xl p-3 flex flex-col gap-1 text-left transition-all duration-200 focus:outline-none" style="background-color: rgb(232, 231, 227);"><p class="text-12 font-semibold tracking-widest uppercase leading-tight text-gray-400">HOURS SAVED</p><p class="text-lg font-bold leading-tight transition-colors duration-300" style="color: rgb(31, 41, 55);">20+</p></button><button class="rounded-xl p-3 flex flex-col gap-1 text-left transition-all duration-200 focus:outline-none" style="background-color: rgb(232, 231, 227);"><p class="text-12 font-semibold tracking-widest uppercase leading-tight text-gray-400">AWARENESS</p><p class="text-lg font-bold leading-tight transition-colors duration-300" style="color: rgb(31, 41, 55);">500,000+</p></button></div></div></div></div></div></main></div></div> 329 330 <!-- 331 No trackers in this file. Nothing in it can read VITE_ANALYTICS, and Vite 332 serves it as it is in dev and in the e2e suite, so a tag pasted here 333 reports from every local session and every e2e run into the real 334 accounts. The Google tag, the Meta pixel, the OpenAI pixel, PostHog and 335 Clarity load from src/lib/, in the production build only. GTM is gone: 336 GTM-PH3XWHJ5 publishes no tags, and in production Cloudflare's Google tag 337 gateway (/2j52/) loads it first-party on every page anyway. 338 Pinned by frontend/tests/index-html-loads-no-trackers.test.ts. 339 --> 340 341 <!-- DNS Prefetch for deferred third-party scripts --> 342 <link rel="dns-prefetch" href="https://www.googletagmanager.com"> 343 <link rel="dns-prefetch" href="https://www.google-analytics.com"> 344 <link rel="dns-prefetch" href="https://js.stripe.com"> 345
346<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"c5c5699a9bce4190bdf6541584b62159","r":1,"spa":2}' crossorigin="anonymous"></script>
346 347</body></html>
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.