* Place inside , BEFORE any analytics scripts on shop. * * Debug: * ?ssl_debug=1 in the URL prints what the script is doing to the console. * --------------------------------------------------------------------------- */ (function () { 'use strict'; // ------------------------------------------------------------------------- // Configuration // ------------------------------------------------------------------------- var BRIDGE_VERSION = '2026.09.21-2'; var APEX_DOMAIN = '.superstratumlabs.com'; var SHOP_HOST = 'shop.superstratumlabs.com'; // The marketing apex ships its own React link decorator (shopLinkAttribution), // which also re-decorates in-place href rewrites this script's observer cannot // see. On the apex this script only CAPTURES origin; it decorates on other // hosts (e.g. calculator.*) that have no bundle. One decorator per host. var APEX_HOST_RE = /^(www\.)?superstratumlabs\.com$/i; var COOKIE_NAME = 'utm_data'; // SESSION-SCOPED, ROLLING. This cookie is not a history store — GA4 and the // BigQuery export own long-term navigation. Its only job is to carry the // CURRENT session's origin across the apex/calculator/shop hops so the last // click survives into Shopify, which cannot resolve it itself. // // 30 minutes of inactivity matches how both GA4 and Shopify define a session, // and the window slides on every page view (see touchCookie), so an active // journey of any length is covered. // // The previous 90-day TTL is what produced the stale-credit bug: with nothing // expiring, buildShopParams fell back to a months-old first touch. Order // #19572 forwarded a 34-day-old Klaviyo campaign onto a visit whose real // referrer was bing.com. A session-length cookie removes that class of error // at the root rather than patching it. var SESSION_MINUTES = 30; var COOKIE_TTL = 60 * SESSION_MINUTES; var DEBUG = /[?&]ssl_debug=1/.test(location.search); var MAX_PATH_LEN = 256; // Hosts whose links we decorate. SHOP ONLY, deliberately. // // Every hop between apex / calculator / shop shares the `.superstratumlabs.com` // cookie, so origin already travels with the visitor on internal hops without // any decoration. Decoration exists for exactly one reason: Shopify reads // attribution from the HTTP request, server-side, before any script runs. So // the ONLY hop that must carry params is the last one into shop. // // This holds for every path shape — apex→calculator→apex→shop, // shop→apex→shop, calculator→shop→apex→shop — because whichever host owns // that final hop (React on apex, this script on calculator) builds the params // from the same shared cookie. // // Decorating internal apex/calculator links would be redundant, would leak // campaign params into shareable URLs, and would feed our own synthesised // params back into capture on the next host. var LINK_TARGETS = ['shop.superstratumlabs.com']; // Tracking params we will capture / forward / restore var UTM_PARAMS = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content','utm_id','utm_source_platform']; var CLICK_IDS = ['gclid','fbclid','ttclid','msclkid','wbraid','gbraid','yclid','irclickid','epik','li_fat_id','rdt_cid','twclid','gad_source','ScCid']; var EXTRA_PARAMS = ['ref','source','aff_id','aff_sub']; var ALL_PARAMS = UTM_PARAMS.concat(CLICK_IDS).concat(EXTRA_PARAMS); // Referrer → source/medium, matched in order. Anything unmatched and external // falls through to { source: , medium: 'referral' }. var REFERRER_RULES = [ { re: /(^|\.)mail\.google\.com$/, source: 'gmail', medium: 'email' }, { re: /(^|\.)google\.[a-z.]+$/, source: 'google', medium: 'organic' }, { re: /(^|\.)bing\.com$/, source: 'bing', medium: 'organic' }, { re: /(^|\.)duckduckgo\.com$/, source: 'duckduckgo', medium: 'organic' }, { re: /(^|\.)search\.yahoo\.[a-z.]+$/,source: 'yahoo', medium: 'organic' }, { re: /(^|\.)ecosia\.org$/, source: 'ecosia', medium: 'organic' }, { re: /(^|\.)search\.brave\.com$/, source: 'brave', medium: 'organic' }, { re: /(^|\.)yandex\.[a-z.]+$/, source: 'yandex', medium: 'organic' }, { re: /(^|\.)baidu\.com$/, source: 'baidu', medium: 'organic' }, { re: /(^|\.)startpage\.com$/, source: 'startpage', medium: 'organic' }, { re: /(^|\.)facebook\.com$/, source: 'facebook', medium: 'social' }, { re: /(^|\.)fb\.(com|me)$/, source: 'facebook', medium: 'social' }, { re: /(^|\.)instagram\.com$/, source: 'instagram', medium: 'social' }, { re: /(^|\.)t\.co$/, source: 'twitter', medium: 'social' }, { re: /(^|\.)(twitter|x)\.com$/, source: 'twitter', medium: 'social' }, { re: /(^|\.)linkedin\.com$/, source: 'linkedin', medium: 'social' }, { re: /(^|\.)lnkd\.in$/, source: 'linkedin', medium: 'social' }, { re: /(^|\.)pinterest\.[a-z.]+$/, source: 'pinterest', medium: 'social' }, { re: /(^|\.)reddit\.com$/, source: 'reddit', medium: 'social' }, { re: /(^|\.)tiktok\.com$/, source: 'tiktok', medium: 'social' }, { re: /(^|\.)youtube\.com$/, source: 'youtube', medium: 'social' }, { re: /(^|\.)threads\.(net|com)$/, source: 'threads', medium: 'social' }, { re: /(^|\.)snapchat\.com$/, source: 'snapchat', medium: 'social' }, { re: /(^|\.)whatsapp\.com$/, source: 'whatsapp', medium: 'social' }, { re: /(^|\.)linktr\.ee$/, source: 'linktree', medium: 'referral'}, { re: /(^|\.)shop\.app$/, source: 'shop_app', medium: 'referral'} ]; // ------------------------------------------------------------------------- // Utilities // ------------------------------------------------------------------------- function log() { if (!DEBUG) return; try { console.log.apply(console, ['[ssl-origin-bridge]'].concat([].slice.call(arguments))); } catch (e) {} } function getCookie(name) { var m = document.cookie.match(new RegExp('(?:^|; )' + name.replace(/([.$?*|{}()[\]\\\/+^])/g, '\\$1') + '=([^;]*)')); return m ? decodeURIComponent(m[1]) : null; } function setCookie(name, value) { document.cookie = name + '=' + encodeURIComponent(value) + '; domain=' + APEX_DOMAIN + '; path=/' + '; max-age=' + COOKIE_TTL + '; SameSite=Lax' + (location.protocol === 'https:' ? '; Secure' : ''); } function parseCookieJSON(name) { var raw = getCookie(name); if (!raw) return {}; try { return JSON.parse(raw); } catch (e) { return {}; } } function getQuery() { var out = {}; var qs = location.search.replace(/^\?/, ''); if (!qs) return out; qs.split('&').forEach(function (p) { var i = p.indexOf('='); if (i < 0) { out[decodeURIComponent(p)] = ''; return; } out[decodeURIComponent(p.slice(0, i))] = decodeURIComponent(p.slice(i + 1)); }); return out; } function isInternalReferrer(ref) { return /^https?:\/\/([a-z0-9-]+\.)?superstratumlabs\.com/i.test(ref || ''); } function onReady(fn) { if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', fn); else fn(); } function trimPath(p) { if (!p) return p; return p.length > MAX_PATH_LEN ? p.slice(0, MAX_PATH_LEN) : p; } /** * Classify a referrer into { source, medium }, GA4-style. * Returns direct/none for an empty or unparseable referrer, and null for an * internal referrer (nothing to learn from our own domains). */ function classifyReferrer(ref) { if (!ref) return { source: 'direct', medium: 'none' }; if (isInternalReferrer(ref)) return null; var host; try { host = new URL(ref).hostname.toLowerCase(); } catch (e) { return { source: 'direct', medium: 'none' }; } if (!host) return { source: 'direct', medium: 'none' }; for (var i = 0; i < REFERRER_RULES.length; i++) { if (REFERRER_RULES[i].re.test(host)) { return { source: REFERRER_RULES[i].source, medium: REFERRER_RULES[i].medium }; } } return { source: host.replace(/^www\./, ''), medium: 'referral' }; } function decorateTargets() { var here = (location.hostname || '').toLowerCase(); return LINK_TARGETS.filter(function (h) { return h !== here; }); } // ------------------------------------------------------------------------- // 1. Origin capture (runs on every host) // ------------------------------------------------------------------------- function captureOrigin() { var existing = parseCookieJSON(COOKIE_NAME); var qp = getQuery(); var changed = false; var hasAnyTrackingParam = ALL_PARAMS.some(function (k) { return qp[k]; }); var ref = document.referrer || ''; var externalRef = !!ref && !isInternalReferrer(ref); if (!existing.captured_at) { // FIRST TOUCH. // Unconditional (FIX 2): previously this required a tracking param or an // external referrer, so true-direct arrivals wrote nothing and their // outbound links went bare — which Shopify then booked as a self-referral. ALL_PARAMS.forEach(function (k) { if (qp[k]) existing[k] = qp[k]; }); // FIX 1: derive source/medium from the referrer when the URL carried no // campaign of its own. Never overwrites an authored utm_source. if (!existing.utm_source) { var derived = classifyReferrer(externalRef ? ref : ''); if (derived) { existing.utm_source = derived.source; if (!existing.utm_medium) existing.utm_medium = derived.medium; existing.source_derived = '1'; } } existing.captured_at = new Date().toISOString(); existing.landing_host = location.hostname; existing.landing_path = trimPath(location.pathname + (location.search || '')); existing.landing_referrer = ref || null; changed = true; log('first-touch captured', existing); } else if (existing.source_derived === '1' && hasAnyTrackingParam) { // PROVISIONAL UPGRADE. // A derived first-touch (direct / organic / referral, synthesised because // the URL carried no campaign) is provisional: it exists so the visitor // is never invisible, not to claim acquisition. The first REAL campaign // to arrive takes the first-touch slot, which is what the old gate // achieved by refusing to write at all. // old: untagged visit writes nothing -> later ad becomes first-touch // new: untagged visit writes `direct` -> later ad REPLACES it // Same attribution outcome, minus the 26% of orders that were arriving // with no origin at all. ALL_PARAMS.forEach(function (k) { if (qp[k]) existing[k] = qp[k]; }); delete existing.source_derived; if (!existing.first_seen_at) existing.first_seen_at = existing.captured_at; existing.captured_at = new Date().toISOString(); existing.landing_host = location.hostname; existing.landing_path = trimPath(location.pathname + (location.search || '')); existing.landing_referrer = ref || existing.landing_referrer || null; changed = true; log('provisional first-touch upgraded to campaign', existing.utm_source); } else if (hasAnyTrackingParam) { // LAST TOUCH via explicit campaign params. First-touch keys stay frozen, // so order ssl_utm_* attributes remain comparable across history while // ssl_last_utm_* carries the current campaign. ALL_PARAMS.forEach(function (k) { if (!qp[k]) return; var lastKey = 'last_' + k; var current = existing[lastKey] != null ? existing[lastKey] : existing[k]; if (qp[k] !== current) { existing[lastKey] = qp[k]; changed = true; } }); if (changed) { // An explicit campaign supersedes any previously derived last-touch. delete existing.last_source_derived; existing.last_touch_at = new Date().toISOString(); existing.last_touch_host = location.hostname; log('last-touch refreshed (campaign)', existing); } } else if (externalRef) { // FIX 3: LAST TOUCH via referrer change. Under the old 90-day TTL this // was what let a month-old email campaign keep winning against a fresh // organic visit. The 30-min scope now retires most of those on its own; // this branch covers the rest — a real origin change inside one session. var d = classifyReferrer(ref); if (d) { var currentSource = existing.last_utm_source != null ? existing.last_utm_source : existing.utm_source; if (d.source !== currentSource) { existing.last_utm_source = d.source; existing.last_utm_medium = d.medium; existing.last_source_derived = '1'; existing.last_touch_at = new Date().toISOString(); existing.last_touch_host = location.hostname; changed = true; log('last-touch refreshed (referrer)', d.source, d.medium); } } } if (changed) setCookie(COOKIE_NAME, JSON.stringify(existing)); else if (existing.captured_at) touchCookie(existing); return existing; } /** * Slide the session window. Re-writes the cookie unchanged with a fresh * max-age on every page view, so an active journey never expires mid-flight * while an abandoned one lapses after SESSION_MINUTES of inactivity — * the same rule GA4 and Shopify use to bound a session. */ function touchCookie(data) { try { setCookie(COOKIE_NAME, JSON.stringify(data)); } catch (e) {} } // ------------------------------------------------------------------------- // 2. Link / form decorator (calculator + previews; NOT apex) // ------------------------------------------------------------------------- /** * FIX 5. Is the source we would forward one this script SYNTHESISED as * direct, rather than one the visitor actually arrived with? * * classifyReferrer() returns direct/none for an arrival with no referrer and * no campaign. STORING that is right — it keeps the visitor visible and stops * Shopify inventing a self-referral (FIX 2). FORWARDING it is wrong: GA4's * Direct channel matches source `(direct)` with medium `(none)`/`(not set)`, * so the bare strings `direct`/`none` match no channel rule at all and the * session drops into Unassigned. * * Suppressing is safe because GA4 already resolves these correctly on its * own: over the same 30 days there were ZERO sessions attributed to * superstratumlabs.com, so cross-domain continuity is intact and nothing * falls back to a self-referral on the GA4 side. The ssl_origin_* params * below still travel, and the shop still stamps ssl_* cart attributes, so the * ORDER keeps the origin even though the URL stays clean. What we give up is * Shopify's native report for this slice, which is the lesser report — GA4 * and the BigQuery export are the system of record. * * Only ever suppresses a value this script invented. A real campaign on the * current URL, or a stored campaign from a real click, always wins. */ function isDerivedDirect(data, qp) { if (qp && (qp.utm_source || qp.utm_medium)) return false; if (data.last_utm_source) { return data.last_source_derived === '1' && data.last_utm_source === 'direct'; } return data.source_derived === '1' && data.utm_source === 'direct'; } function buildShopParams() { var data = parseCookieJSON(COOKIE_NAME); var qp = getQuery(); var out = {}; var dropDirect = isDerivedDirect(data, qp); // Precedence: current-URL param (this hop) > stored last-touch > frozen // first-touch. A live campaign click still wins over the cookie, and // decorated links carry the most recent campaign, not the frozen first. UTM_PARAMS.concat(CLICK_IDS).forEach(function (k) { var v = qp[k] || data['last_' + k] || data[k]; if (!v) return; // Click IDs still travel: a gclid/fbclid is real even when the referrer // was empty, and GA4 resolves those to google/cpc itself. if (dropDirect && (k === 'utm_source' || k === 'utm_medium')) return; out[k] = v; }); if (data.captured_at) out.ssl_origin_at = data.captured_at; if (data.landing_host) out.ssl_origin_host = data.landing_host; if (data.landing_path) out.ssl_origin_path = data.landing_path; return out; } function decorateUrl(urlStr) { var u; try { u = new URL(urlStr, location.href); } catch (e) { return urlStr; } if (decorateTargets().indexOf((u.hostname || '').toLowerCase()) === -1) return urlStr; var params = buildShopParams(); var search = new URLSearchParams(u.search); Object.keys(params).forEach(function (k) { // Authored params win: a link that hardcodes utm_* keeps it. if (!search.has(k)) search.set(k, params[k]); }); u.search = search.toString(); return u.toString(); } function decorateAnchor(a) { try { var href = a.getAttribute('href'); if (!href || /^(mailto:|tel:|javascript:|#)/i.test(href)) return; if (a.getAttribute('data-ssl-decorated') === '1') return; var newHref = decorateUrl(href); if (newHref !== href) { a.setAttribute('href', newHref); a.setAttribute('data-ssl-decorated', '1'); } } catch (e) {} } function decorateForm(form) { try { var action = form.getAttribute('action'); if (!action) return; if (form.getAttribute('data-ssl-decorated') === '1') return; var u; try { u = new URL(action, location.href); } catch (e) { return; } if (decorateTargets().indexOf((u.hostname || '').toLowerCase()) === -1) return; var params = buildShopParams(); Object.keys(params).forEach(function (k) { if (form.querySelector('input[name="' + k + '"]')) return; var input = document.createElement('input'); input.type = 'hidden'; input.name = k; input.value = params[k]; form.appendChild(input); }); form.setAttribute('data-ssl-decorated', '1'); } catch (e) {} } function decorateAll() { var anchors = document.querySelectorAll('a[href]'); for (var i = 0; i < anchors.length; i++) decorateAnchor(anchors[i]); var forms = document.querySelectorAll('form[action]'); for (var j = 0; j < forms.length; j++) decorateForm(forms[j]); log('decorated initial links', anchors.length, 'forms', forms.length); } function watchMutations() { if (!window.MutationObserver) return; var obs = new MutationObserver(function (muts) { muts.forEach(function (m) { if (!m.addedNodes) return; m.addedNodes.forEach(function (n) { if (n.nodeType !== 1) return; if (n.tagName === 'A' && n.hasAttribute('href')) decorateAnchor(n); else if (n.tagName === 'FORM' && n.hasAttribute('action')) decorateForm(n); else if (n.querySelectorAll) { n.querySelectorAll('a[href]').forEach(decorateAnchor); n.querySelectorAll('form[action]').forEach(decorateForm); } }); }); }); obs.observe(document.documentElement, { childList: true, subtree: true }); } function backstopClick() { // Catches programmatic .click() and last-second href swaps. document.addEventListener('click', function (e) { var a = e.target && e.target.closest ? e.target.closest('a[href]') : null; if (a) decorateAnchor(a); }, true); document.addEventListener('submit', function (e) { var f = e.target; if (f && f.tagName === 'FORM') decorateForm(f); }, true); } // ------------------------------------------------------------------------- // 3. Shop-side reconciler // NOTE: this cannot repair Shopify's own attribution — Shopify records // landing_site from the HTTP request, before any script runs. Kept as // best-effort for GTM/dataLayer consumers only. The attribution fix is // decoration on the originating host, above. // ------------------------------------------------------------------------- function reconcileShopUrl() { var data = parseCookieJSON(COOKIE_NAME); if (!data || !Object.keys(data).length) { log('shop reconcile: no cookie data'); return false; } var qp = getQuery(); var alreadyHasUtm = UTM_PARAMS.some(function (k) { return qp[k]; }); if (alreadyHasUtm) { log('shop reconcile: URL already has UTMs'); return false; } var params = new URLSearchParams(location.search); var added = 0; var dropDirect = isDerivedDirect(data, qp); // FIX 5 — see isDerivedDirect UTM_PARAMS.concat(CLICK_IDS).forEach(function (k) { if (dropDirect && (k === 'utm_source' || k === 'utm_medium')) return; // Prefer last-touch, fall back to frozen first-touch. var v = (data['last_' + k] != null ? data['last_' + k] : data[k]); if (v && !params.has(k)) { params.set(k, v); added++; } }); if (!added) return false; var newQs = params.toString(); var newUrl = location.pathname + (newQs ? '?' + newQs : '') + location.hash; try { history.replaceState(history.state, '', newUrl); log('shop reconcile: URL rewritten with', added, 'params'); return true; } catch (e) { log('replaceState failed', e); return false; } } function pushDataLayer() { var data = parseCookieJSON(COOKIE_NAME); if (!data || !Object.keys(data).length) return; window.dataLayer = window.dataLayer || []; var payload = { event: 'ssl_origin_ready' }; Object.keys(data).forEach(function (k) { payload['ssl_' + k] = data[k]; }); window.dataLayer.push(payload); log('dataLayer pushed', payload); } function stampCartAttributes() { if (!window.fetch) return; var data = parseCookieJSON(COOKIE_NAME); if (!data || !Object.keys(data).length) return; var pairs = []; Object.keys(data).forEach(function (k) { pairs.push( encodeURIComponent('attributes[ssl_' + k + ']') + '=' + encodeURIComponent(String(data[k] == null ? '' : data[k])) ); }); if (!pairs.length) return; fetch('/cart/update.js', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json' }, body: pairs.join('&'), credentials: 'same-origin', keepalive: true }).then(function (r) { log('cart.attributes stamped', r.status); }) .catch(function (e) { log('cart.attributes error', e); }); } // ------------------------------------------------------------------------- // Boot // ------------------------------------------------------------------------- var mode = location.hostname === SHOP_HOST ? 'shop' : (APEX_HOST_RE.test(location.hostname) ? 'apex-capture-only' : 'decorate'); // FIX 4: make the deployed build identifiable from outside. try { window.__sslOriginBridge = { version: BRIDGE_VERSION, host: location.hostname, mode: mode, targets: decorateTargets() }; } catch (e) {} // Always capture first — works on all three hosts. captureOrigin(); if (mode === 'shop') { // Reconcile URL SYNC, before Shopify analytics beacons fire. reconcileShopUrl(); // Push to dataLayer SYNC too (so GTM tags reading dataLayer see it). pushDataLayer(); // Cart attribute stamp can wait for DOMContentLoaded. onReady(stampCartAttributes); } else if (mode === 'apex-capture-only') { // Apex: capture only. shopLinkAttribution (React bundle) owns decoration, // because it alone re-decorates React's in-place href rewrites. log('apex host: capture only, React bundle decorates links', BRIDGE_VERSION); } else { // Other hosts (calculator.*, previews) have no bundle — decorate here. onReady(function () { decorateAll(); watchMutations(); backstopClick(); }); } })();

Home doesn't fit a standard kit?

Use the WHD Calculator for a custom order.

BUILD MY CUSTOM ORDER →
BRI EMERGENCY KIT

YOUR FIRST RESPONSE PROTOCOL

Active mold or just starting out? The BRI Emergency Kit gives you the immediate tools for home and body — fogging kit plus nasal support.

Product Image

SHOP BY STEP

The Whole Home Detox Protocol

MAINTENANCE ESSENTIALS

Your regular home health routine.

01 — CLEAN

Cleaners

02 — GAS

Deodor Bombs

03 — COAT

Coatings

TARGETED SOLUTIONS

Shop by Space

ESSENTIAL SETS

Value Bundles

EQUIPMENT & PPE

Tools for the Protocol

BUG DEFENSE

Natural Protection