PageSourceSearch

https://chrisgee.ai/js/ga-events.js

js chrisgee.ai collected 2026-10-09 23:22:05 UTC 2,438 bytes, 59 lines download raw bytes

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.