- Created /js/pw-analytics.js with conversion funnel events - Added to Base.astro layout (all Astro pages) + 6 static HTML pages - Events tracked: compliance-check-start, compliance-check-complete, order-cta-click, checkout-page-view, checkout-start, esign-opened, esign-submitted, campaign-click (UTM attribution), contact-form-submit - Server-side payment-complete event from checkout webhook via Umami API - Auto-tracks any element with data-track="event-name" attribute Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
129 lines
5.3 KiB
JavaScript
129 lines
5.3 KiB
JavaScript
/**
|
|
* Performance West — Umami custom event tracking.
|
|
* Loaded after the Umami script on all pages.
|
|
* Uses umami.track() for conversion funnel events.
|
|
*/
|
|
(function() {
|
|
// Wait for umami to be available
|
|
function track(name, data) {
|
|
if (window.umami) {
|
|
window.umami.track(name, data || {});
|
|
}
|
|
}
|
|
|
|
// Expose globally for inline usage
|
|
window.pwTrack = track;
|
|
|
|
// ── Auto-track common interactions ────────────────────────────────────
|
|
|
|
// Track all CTA button clicks with data-track attribute
|
|
document.addEventListener("click", function(e) {
|
|
var el = e.target.closest("[data-track]");
|
|
if (el) {
|
|
track(el.getAttribute("data-track"), {
|
|
label: el.textContent.trim().slice(0, 50),
|
|
href: el.href || "",
|
|
page: location.pathname,
|
|
});
|
|
}
|
|
});
|
|
|
|
// ── FCC Compliance Checker events ─────────────────────────────────────
|
|
|
|
// Check if we're on the compliance checker page
|
|
if (location.pathname.indexOf("/tools/fcc-compliance-check") === 0) {
|
|
// Track when check starts (form submit / button click)
|
|
var checkBtn = document.querySelector("#check-btn, [onclick*='runCheck'], button[type='submit']");
|
|
if (checkBtn) {
|
|
checkBtn.addEventListener("click", function() {
|
|
var frn = (document.querySelector("#frn-input, input[name='frn']") || {}).value || "";
|
|
track("compliance-check-start", { frn: frn });
|
|
});
|
|
}
|
|
|
|
// Track when results load (observe DOM for results container)
|
|
var observer = new MutationObserver(function(mutations) {
|
|
for (var i = 0; i < mutations.length; i++) {
|
|
var target = mutations[i].target;
|
|
if (target.id === "checks-container" || target.id === "results") {
|
|
var issues = document.querySelectorAll(".check-fail, .issue-card, [data-severity]").length;
|
|
var frn = (document.querySelector("#frn-input, input[name='frn']") || {}).value || "";
|
|
track("compliance-check-complete", { frn: frn, issues: issues });
|
|
observer.disconnect();
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
var resultsEl = document.getElementById("checks-container") || document.getElementById("results");
|
|
if (resultsEl) {
|
|
observer.observe(resultsEl, { childList: true, subtree: true });
|
|
}
|
|
|
|
// Track "Order" CTA clicks from results
|
|
document.addEventListener("click", function(e) {
|
|
var btn = e.target.closest("a[href*='/order/'], button[data-slug]");
|
|
if (btn && (btn.closest("#checks-container") || btn.closest("#results") || btn.closest(".cta"))) {
|
|
var slug = btn.getAttribute("data-slug") || btn.href.split("/order/")[1] || "";
|
|
track("order-cta-click", {
|
|
slug: slug.split("/")[0] || slug.split("?")[0],
|
|
source: "compliance-checker",
|
|
page: location.pathname,
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
// ── Order / Checkout pages ────────────────────────────────────────────
|
|
|
|
if (location.pathname.indexOf("/order/") === 0) {
|
|
// Track checkout page view with service info
|
|
var slug = location.pathname.replace("/order/", "").replace(/\/$/, "");
|
|
track("checkout-page-view", { slug: slug, referrer: document.referrer });
|
|
|
|
// Track payment button click
|
|
document.addEventListener("click", function(e) {
|
|
var btn = e.target.closest("#pay-btn, #submit-btn, .checkout-btn, button[type='submit']");
|
|
if (btn && (btn.textContent.indexOf("Pay") >= 0 || btn.textContent.indexOf("Checkout") >= 0 || btn.textContent.indexOf("Place Order") >= 0)) {
|
|
track("checkout-start", { slug: slug, page: location.pathname });
|
|
}
|
|
});
|
|
}
|
|
|
|
// ── eSign portal ──────────────────────────────────────────────────────
|
|
|
|
if (location.pathname.indexOf("/portal/esign") === 0 || location.pathname.indexOf("/portal/sign") === 0) {
|
|
track("esign-opened", { page: location.pathname });
|
|
|
|
document.addEventListener("click", function(e) {
|
|
var btn = e.target.closest("#submit-btn, .submit-btn");
|
|
if (btn && btn.textContent.indexOf("Submit") >= 0) {
|
|
track("esign-submitted", { page: location.pathname });
|
|
}
|
|
});
|
|
}
|
|
|
|
// ── Email campaign click attribution ──────────────────────────────────
|
|
|
|
var params = new URLSearchParams(location.search);
|
|
var utmSource = params.get("utm_source");
|
|
var utmCampaign = params.get("utm_campaign");
|
|
if (utmSource || utmCampaign) {
|
|
track("campaign-click", {
|
|
source: utmSource || "",
|
|
campaign: utmCampaign || "",
|
|
medium: params.get("utm_medium") || "",
|
|
page: location.pathname,
|
|
});
|
|
}
|
|
|
|
// ── Contact form submission ───────────────────────────────────────────
|
|
|
|
if (location.pathname.indexOf("/contact") === 0) {
|
|
document.addEventListener("submit", function(e) {
|
|
if (e.target.closest("form")) {
|
|
track("contact-form-submit", { page: location.pathname });
|
|
}
|
|
});
|
|
}
|
|
|
|
})();
|