// Google Ads (gtag) — lazily injected so it stays out of the initial bundle and // off entirely when VITE_GOOGLE_ADS_ID is unset (dev/preview). All exported // functions are fire-and-forget; tracking loss on failure is acceptable. // // Reports conversions client-side to Google Ads. The Google tag auto-captures // gclid into its own _gcl_* cookies for click attribution; we additionally stash // the raw gclid in a first-party cookie so a future server-side conversion import // (Google Ads API, gated on Basic access) can attribute the same click. type GtagArgs = unknown[]; declare global { interface Window { gtag?: (...args: GtagArgs) => void; dataLayer?: GtagArgs[]; } } let _initialized = false; let _adsId: string | undefined; function captureGclid(): void { try { const p = new URLSearchParams(window.location.search); const gclid = p.get("gclid") || p.get("gbraid") || p.get("wbraid"); if (gclid) { // 90-day first-party cookie for later server-side conversion import. document.cookie = `sase_gclid=${encodeURIComponent(gclid)}; path=/; max-age=${90 * 24 * 60 * 60}; SameSite=Lax`; } } catch { // URL/cookie access can throw in locked-down embeds — ignore. } } export function initGoogleAds(): void { const id = import.meta.env.VITE_GOOGLE_ADS_ID; // e.g. "AW-1234567890" if (!id || _initialized || typeof window === "undefined") return; _initialized = true; _adsId = id; window.dataLayer = window.dataLayer || []; // gtag.js executes only queue entries that are the `arguments` object; pushing a // plain array (rest params → `args`) is stored as inert dataLayer data and the // command (config/event) NEVER runs. That silently disabled ALL conversion // tracking — no _gcl_aw linker cookie, no conversion pings, 0 conversions in the // panel. Use Google's canonical snippet form that pushes `arguments`. function gtag() { // biome-ignore lint/style/noArguments: gtag.js only processes the raw arguments object window.dataLayer?.push(arguments as unknown as GtagArgs); } if (!window.gtag) window.gtag = gtag; const script = document.createElement("script"); script.async = true; script.src = `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(id)}`; const first = document.getElementsByTagName("script")[0]; first?.parentNode?.insertBefore(script, first); window.gtag("js", new Date()); // allow_enhanced_conversions lets hashed first-party data (email set below) // improve match rate without exposing PII to the page. window.gtag("config", id, { allow_enhanced_conversions: true }); captureGclid(); } // Enhanced Conversions: provide first-party data; the tag hashes it in-browser. export function setGoogleAdsUserData(email?: string): void { if (!_initialized || !email) return; window.gtag?.("set", "user_data", { email }); } // Fire a conversion. `label` is the conversion action's label (from Google Ads // → Conversions); the event is sent to "/