Created
April 14, 2026 16:39
-
-
Save ceaksan/e3708eda7d73bc9a0b0fd5e8935a5549 to your computer and use it in GitHub Desktop.
GTM Custom HTML Tag: Send purchase event data + first-party cookie attribution (dnm_src/dnm_cid) to Umami via umami.track(). Cookie-less attribution debugging alongside GA4.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * GTM Custom HTML Tag — Umami purchase event bridge | |
| * File: gtm-umami-purchase-bridge.js | |
| * | |
| * What it does: | |
| * Sends purchase event data + first-party cookie attribution | |
| * to Umami via umami.track(). Runs alongside GA4 purchase tag | |
| * to create an independent, cookie-less attribution record. | |
| * | |
| * Parameters sent to Umami: | |
| * transaction_id → e.g. "ORD-2026-1234" | |
| * value → e.g. 1250.00 | |
| * currency → e.g. "TRY" | |
| * ft_source → e.g. "google" (from dnm_src cookie) | |
| * ft_medium → e.g. "cpc" (from dnm_src cookie) | |
| * ft_campaign → e.g. "TR_branded" (from dnm_src cookie) | |
| * ft_click_id → e.g. "gclid:Cj0K..." (from dnm_cid cookie) | |
| * | |
| * Requires: | |
| * - Umami script loaded on page (umami.track must be available) | |
| * - storageHelper (see companion gist) loaded BEFORE this tag | |
| * - ecommerce dataLayer push with transaction_id, value, currency | |
| * | |
| * Trigger: | |
| * Purchase event trigger (same as GA4 purchase tag). | |
| * Tag Sequencing: after storageHelper. | |
| * Consent condition: analytics_storage = granted. | |
| * | |
| * Fails silently if Umami script is blocked (ad blocker) | |
| * or not yet loaded. | |
| */ | |
| (function () { | |
| if (typeof umami === "undefined" || typeof umami.track !== "function") { | |
| return; | |
| } | |
| /* --- 1. Read ecommerce data from dataLayer ---------------------- */ | |
| var dl = window.dataLayer || []; | |
| var ecomm = null; | |
| for (var i = dl.length - 1; i >= 0; i--) { | |
| if (dl[i].ecommerce && dl[i].ecommerce.transaction_id) { | |
| ecomm = dl[i].ecommerce; | |
| break; | |
| } | |
| } | |
| var transactionId = ecomm ? String(ecomm.transaction_id) : ""; | |
| var value = ecomm ? Number(ecomm.value) || 0 : 0; | |
| var currency = ecomm ? String(ecomm.currency || "TRY") : "TRY"; | |
| /* --- 2. Read first-party cookie attribution --------------------- */ | |
| var rawSource = storageHelper.get("dnm_src"); | |
| var rawCid = storageHelper.get("dnm_cid"); | |
| var parts = rawSource ? String(rawSource).split("|") : []; | |
| var ftSource = parts[0] || "(not set)"; | |
| var ftMedium = parts[1] || "(not set)"; | |
| var ftCampaign = parts[2] || "(not set)"; | |
| var ftClickId = rawCid ? String(rawCid) : "(not set)"; | |
| /* --- 3. Send to Umami ------------------------------------------- */ | |
| umami.track("purchase", { | |
| transaction_id: transactionId, | |
| value: value, | |
| currency: currency, | |
| ft_source: ftSource, | |
| ft_medium: ftMedium, | |
| ft_campaign: ftCampaign, | |
| ft_click_id: ftClickId, | |
| }); | |
| /* --- 4. Debug log ----------------------------------------------- */ | |
| if (window.location.search.indexOf("dnm_debug=1") !== -1) { | |
| console.group("[DNM] Umami purchase bridge"); | |
| console.log("transaction_id :", transactionId); | |
| console.log("value :", value, currency); | |
| console.log("ft_source :", ftSource); | |
| console.log("ft_medium :", ftMedium); | |
| console.log("ft_campaign :", ftCampaign); | |
| console.log("ft_click_id :", ftClickId); | |
| console.groupEnd(); | |
| } | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment