1/* GA4 conversion events for chrisgee.ai 2 Loads on every page after the Google tag (gtag.js). Uses event delegation, 3 so no per-CTA markup is required. If GA is blocked (e.g. pre-consent), 4 gtag() simply queues to dataLayer and flushes once consent loads. */ 5(function () { 6 "use strict"; 7 8 function ev(name, params) { 9 if (typeof window.gtag !== "function") return; 10 try { window.gtag("event", name, params || {}); } catch (e) {} 11 } 12 function linkText(a) { 13 return (a.textContent || "").trim().replace(/\s+/g, " ").slice(0, 100); 14 } 15 16 // Offer pages -> the offer name reported on the event 17 var OFFER = { 18 "/workshop": "workshop", 19 "/ai-strategy-sprint": "strategy_sprint", 20 "/advisory": "advisory", 21 "/ai-audit": "ai_audit", 22 "/sessions": "power_hour" 23 }; 24 25 // ---- Delegated link-click tracking ---- 26 document.addEventListener("click", function (e) { 27 var a = e.target && e.target.closest ? e.target.closest("a[href]") : null; 28 if (!a) return; 29 var raw = a.getAttribute("href") || ""; 30 var path = ""; 31 try { path = new URL(a.href, location.origin).pathname.replace(/\/+$/, ""); } catch (_) {} 32 var base = { link_text: linkText(a), link_url: raw, page_path: location.pathname }; 33 34 if (path === "/ai-discovery-call") { ev("book_call_click", base); return; } // primary CTA intent 35 if (path === "/quiz") { ev("quiz_start", base); return; } 36 if (OFFER[path]) { base.offer = OFFER[path]; ev("offer_click", base); return; } 37 if (/^mailto:/i.test(raw)) { ev("email_click", base); return; } 38 if (a.host && a.host !== location.host && /^https?:$/i.test(a.protocol)) { 39 base.link_domain = a.host; ev("outbound_click", base); return; 40 } 41 }, true); 42 43 // ---- Newsletter (Kit) form submit ---- 44 document.addEventListener("submit", function (e) { 45 var f = e.target; 46 if (f && f.tagName === "FORM" && /app\.kit\.com\/forms/.test(f.getAttribute("action") || "")) { 47 ev("newsletter_signup", { page_path: location.pathname }); 48 } 49 }, true); 50 51 // ---- Calendly booking completed -> the real lead conversion ---- 52 window.addEventListener("message", function (e) { 53 if (!e.origin || e.origin.indexOf("calendly.com") === -1) return; 54 var d = e.data; 55 if (d && typeof d === "object" && d.event === "calendly.event_scheduled") { 56 ev("generate_lead", { method: "calendly", page_path: location.pathname }); 57 } 58 }); 59})();
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.