Skip to content

Instantly share code, notes, and snippets.

@akapug
Last active March 13, 2026 00:34
Show Gist options
  • Select an option

  • Save akapug/6e70fa0042eae4122a1d5e4b092a2228 to your computer and use it in GitHub Desktop.

Select an option

Save akapug/6e70fa0042eae4122a1d5e4b092a2228 to your computer and use it in GitHub Desktop.
Referral tracking script for elide.dev website — add to js/utm-capture.js and include in build.mjs head()
From f19980e97eaafe3414a1de9bfeb8183378f4f95d Mon Sep 17 00:00:00 2001
From: David <215816+akapug@users.noreply.github.com>
Date: Thu, 12 Mar 2026 17:31:42 -0700
Subject: [PATCH] feat: add referral tracking & UTM capture script
- Add js/utm-capture.js for UTM parameter and referral attribution tracking
- Modify build.mjs head() to include script on all pages (defer loaded)
- Regenerate all HTML output files
The script captures:
- UTM params (utm_source, utm_medium, utm_campaign) into elide_touchpoints cookie
- Referral codes from ?ref=CODE URL param into elide_ref cookie
- Multi-touch attribution (up to 10 touchpoints, 90-day expiry)
Part of the referral program: glue.elide.work/api/ref/[code] redirects here,
and this script ensures attribution persists for downstream conversion tracking.
---
about.html | 1 +
blog/index.html | 1 +
blog/whiplash/index.html | 1 +
build.mjs | 1 +
index.html | 1 +
js/utm-capture.js | 107 +++++++++++++++++++++++++++++++++++++++
pricing.html | 1 +
7 files changed, 113 insertions(+)
create mode 100644 js/utm-capture.js
diff --git a/about.html b/about.html
index d15d2e9..e675f33 100644
--- a/about.html
+++ b/about.html
@@ -22,6 +22,7 @@
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>
<body>
diff --git a/blog/index.html b/blog/index.html
index dd57eb4..f488730 100644
--- a/blog/index.html
+++ b/blog/index.html
@@ -22,6 +22,7 @@
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>
<body>
diff --git a/blog/whiplash/index.html b/blog/whiplash/index.html
index 2d7487e..a575b16 100644
--- a/blog/whiplash/index.html
+++ b/blog/whiplash/index.html
@@ -22,6 +22,7 @@
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>
<body>
diff --git a/build.mjs b/build.mjs
index 51975ea..45e1d5c 100644
--- a/build.mjs
+++ b/build.mjs
@@ -152,6 +152,7 @@ function head(title, description, url, ogType = "article", ogImage = "https://el
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>`;
}
diff --git a/index.html b/index.html
index bfdf258..0496fd9 100644
--- a/index.html
+++ b/index.html
@@ -22,6 +22,7 @@
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>
<body>
diff --git a/js/utm-capture.js b/js/utm-capture.js
new file mode 100644
index 0000000..18a8976
--- /dev/null
+++ b/js/utm-capture.js
@@ -0,0 +1,107 @@
+/**
+ * Elide UTM Capture Snippet
+ *
+ * Drop this script on any landing page (elide.dev, blog, docs) to capture
+ * UTM parameters and accumulate multi-touch attribution data.
+ *
+ * Usage:
+ * <script src="https://glue.elide.work/js/utm-capture.js" defer></script>
+ *
+ * What it does:
+ * 1. On page load, reads UTM params from the URL (utm_source, utm_medium, utm_campaign)
+ * 2. Reads the referral code cookie (set by /api/ref/[code])
+ * 3. Appends a touchpoint to the elide_touchpoints cookie (JSON array)
+ * 4. When the user clicks a buy/checkout link, the /api/buy endpoint reads
+ * the accumulated touchpoints and sends them to Stripe metadata.
+ *
+ * Cookie format (elide_touchpoints):
+ * [{"source":"youtube","medium":"influencer","campaign":"theo","timestamp":"..."}]
+ *
+ * Respects: No PII is stored. Only UTM params + timestamps.
+ */
+(function () {
+ var COOKIE_NAME = "elide_touchpoints";
+ var MAX_TOUCHPOINTS = 10;
+ var COOKIE_DAYS = 90;
+
+ function getCookie(name) {
+ var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
+ return match ? decodeURIComponent(match[2]) : null;
+ }
+
+ function setCookie(name, value, days) {
+ var expires = new Date(Date.now() + days * 864e5).toUTCString();
+ document.cookie =
+ name +
+ "=" +
+ encodeURIComponent(value) +
+ "; expires=" +
+ expires +
+ "; path=/; SameSite=Lax";
+ }
+
+ function getUtmParams() {
+ var params = new URLSearchParams(window.location.search);
+ var source = params.get("utm_source");
+ if (!source) return null;
+ return {
+ source: source,
+ medium: params.get("utm_medium") || "none",
+ campaign: params.get("utm_campaign") || undefined,
+ timestamp: new Date().toISOString(),
+ };
+ }
+
+ function getReferralCode() {
+ // Check URL param first (?ref=CODE), then cookie (set by /api/ref/[code])
+ var params = new URLSearchParams(window.location.search);
+ var urlRef = params.get("ref");
+ if (urlRef) {
+ setCookie("elide_ref", urlRef, COOKIE_DAYS);
+ return urlRef;
+ }
+ return getCookie("elide_ref") || null;
+ }
+
+ // Read existing touchpoints
+ var existing = [];
+ try {
+ var raw = getCookie(COOKIE_NAME);
+ if (raw) existing = JSON.parse(raw);
+ if (!Array.isArray(existing)) existing = [];
+ } catch (e) {
+ existing = [];
+ }
+
+ // Add UTM touchpoint if present
+ var utm = getUtmParams();
+ if (utm) {
+ existing.push(utm);
+ }
+
+ // Add referral touchpoint if cookie is set and not already tracked
+ var refCode = getReferralCode();
+ if (refCode) {
+ var hasRef = existing.some(function (t) {
+ return t.source === "referral";
+ });
+ if (!hasRef) {
+ existing.push({
+ source: "referral",
+ medium: "user",
+ campaign: refCode,
+ timestamp: new Date().toISOString(),
+ });
+ }
+ }
+
+ // Keep only the last N touchpoints
+ if (existing.length > MAX_TOUCHPOINTS) {
+ existing = existing.slice(-MAX_TOUCHPOINTS);
+ }
+
+ // Persist
+ if (existing.length > 0) {
+ setCookie(COOKIE_NAME, JSON.stringify(existing), COOKIE_DAYS);
+ }
+})();
diff --git a/pricing.html b/pricing.html
index 8b15488..063ac0a 100644
--- a/pricing.html
+++ b/pricing.html
@@ -22,6 +22,7 @@
<link rel="stylesheet" href="/css/reset.css">
<link rel="stylesheet" href="/css/layout.css">
<link rel="stylesheet" href="/css/components.css">
+ <script src="/js/utm-capture.js" defer></script>
</head>
<body>
--
2.51.0
/**
* Elide UTM Capture Snippet
*
* Drop this script on any landing page (elide.dev, blog, docs) to capture
* UTM parameters and accumulate multi-touch attribution data.
*
* Usage:
* <script src="https://glue.elide.work/js/utm-capture.js" defer></script>
*
* What it does:
* 1. On page load, reads UTM params from the URL (utm_source, utm_medium, utm_campaign)
* 2. Reads the referral code cookie (set by /api/ref/[code])
* 3. Appends a touchpoint to the elide_touchpoints cookie (JSON array)
* 4. When the user clicks a buy/checkout link, the /api/buy endpoint reads
* the accumulated touchpoints and sends them to Stripe metadata.
*
* Cookie format (elide_touchpoints):
* [{"source":"youtube","medium":"influencer","campaign":"theo","timestamp":"..."}]
*
* Respects: No PII is stored. Only UTM params + timestamps.
*/
(function () {
var COOKIE_NAME = "elide_touchpoints";
var MAX_TOUCHPOINTS = 10;
var COOKIE_DAYS = 90;
function getCookie(name) {
var match = document.cookie.match(new RegExp("(^| )" + name + "=([^;]+)"));
return match ? decodeURIComponent(match[2]) : null;
}
function setCookie(name, value, days) {
var expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie =
name +
"=" +
encodeURIComponent(value) +
"; expires=" +
expires +
"; path=/; SameSite=Lax";
}
function getUtmParams() {
var params = new URLSearchParams(window.location.search);
var source = params.get("utm_source");
if (!source) return null;
return {
source: source,
medium: params.get("utm_medium") || "none",
campaign: params.get("utm_campaign") || undefined,
timestamp: new Date().toISOString(),
};
}
function getReferralCode() {
// Check URL param first (?ref=CODE), then cookie (set by /api/ref/[code])
var params = new URLSearchParams(window.location.search);
var urlRef = params.get("ref");
if (urlRef) {
setCookie("elide_ref", urlRef, COOKIE_DAYS);
return urlRef;
}
return getCookie("elide_ref") || null;
}
// Read existing touchpoints
var existing = [];
try {
var raw = getCookie(COOKIE_NAME);
if (raw) existing = JSON.parse(raw);
if (!Array.isArray(existing)) existing = [];
} catch (e) {
existing = [];
}
// Add UTM touchpoint if present
var utm = getUtmParams();
if (utm) {
existing.push(utm);
}
// Add referral touchpoint if cookie is set and not already tracked
var refCode = getReferralCode();
if (refCode) {
var hasRef = existing.some(function (t) {
return t.source === "referral";
});
if (!hasRef) {
existing.push({
source: "referral",
medium: "user",
campaign: refCode,
timestamp: new Date().toISOString(),
});
}
}
// Keep only the last N touchpoints
if (existing.length > MAX_TOUCHPOINTS) {
existing = existing.slice(-MAX_TOUCHPOINTS);
}
// Persist
if (existing.length > 0) {
setCookie(COOKIE_NAME, JSON.stringify(existing), COOKIE_DAYS);
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment