GTM Essentials – Variables Container Export
GTM Essentials – Variables Container Export
GTM Container Export (JSON) Last updated: August 2026
Overview
gtm-essentials-variables.json is a Google Tag Manager container export
that creates every GTM Essentials variable in one import — 24 variables, filed
under a GTM Essentials folder, plus GTM's standard built-in variables
switched on. Use it instead of building the variables one by one from the
sibling folders.
The individual Custom JavaScript sources it bundles each live in their own
folder under variables/ with full documentation; this export is just
the fastest way to get all of them into a container at once.
How to Import
- GTM → Admin → Import Container.
- Choose
gtm-essentials-variables.jsonand select your workspace. - Pick Merge and Rename conflicting so nothing existing is overwritten.
- Preview, then Confirm.
Placeholder account/container IDs (0) are remapped into whatever container
you import into, so the file works in any account.
What It Creates
First-party cookie readers (1st-Party Cookie variables) — one 1PC - <cookie> per platform click-ID cookie:
| Variable | Cookie | Platform |
|---|---|---|
1PC - _fbc | _fbc | Meta |
1PC - _fbp | _fbp | Meta |
1PC - fbclid | fbclid | Meta |
1PC - _gcl_aw | _gcl_aw | Google Ads |
1PC - _uetmsclkid | _uetmsclkid | Microsoft Ads |
1PC - _ttp | _ttp | TikTok |
1PC - _twclid | _twclid | Twitter / X |
1PC - li_fat_id | li_fat_id |
Session variables (Custom JS):
cJS - Traffic Source— last-touch traffic source (source).cJS - Ad Placement—utm_placement, persisted per session (source).
Event deduplication:
DLV - gtm.uniqueEventId— Data Layer Variable reading GTM's built-ingtm.uniqueEventIdkey (page-local event counter); feeds the variable below.cJS - Custom Event ID— globally unique event ID for Meta Pixel / CAPI deduplication, cached per{{DLV - gtm.uniqueEventId}}(source).
Page / post / form context (Custom JS):
cJS - Page Title—document.title(source).cJS - Post Title— the page's.entry-title/h1, falling back toog:title(source).cJS - Post ID— the WordPress post/page ID from thepostid-…/page-id-…body class (source).cJS - Form ID— theidof the first<form>on the page (source).
Built-in variables enabled — Click Classes / Element / ID / Target / Text / URL, Event, Form Classes / Element / ID / Target / Text / URL, HTML ID, Page Hostname / Path / URL, and Referrer.
Analytics Client ID is intentionally left out — it has no stable container-export type, so enable it by hand in Configure if you need it (one checkbox).
Keeping It in Sync
This export and the gtm-starter-kit/ bundle both
carry copies of the variables in this directory. If you add, rename, or change
a variable source under variables/, re-export this file and update
the Starter Kit too — otherwise the bundled copies drift from the documented
sources.
The code
{
"exportFormatVersion": 2,
"exportTime": "2026-08-04 00:00:00",
"containerVersion": {
"path": "accounts/0/containers/0/versions/0",
"accountId": "0",
"containerId": "0",
"containerVersionId": "0",
"name": "GTM Essentials",
"container": {
"path": "accounts/0/containers/0",
"accountId": "0",
"containerId": "0",
"name": "GTM Essentials",
"publicId": "GTM-XXXXXXX",
"usageContext": [
"WEB"
],
"fingerprint": "0",
"tagManagerUrl": ""
},
"builtInVariable": [
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_CLASSES",
"name": "Click Classes"
},
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_ELEMENT",
"name": "Click Element"
},
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_ID",
"name": "Click ID"
},
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_TARGET",
"name": "Click Target"
},
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_TEXT",
"name": "Click Text"
},
{
"accountId": "0",
"containerId": "0",
"type": "CLICK_URL",
"name": "Click URL"
},
{
"accountId": "0",
"containerId": "0",
"type": "EVENT",
"name": "Event"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_CLASSES",
"name": "Form Classes"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_ELEMENT",
"name": "Form Element"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_ID",
"name": "Form ID"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_TARGET",
"name": "Form Target"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_TEXT",
"name": "Form Text"
},
{
"accountId": "0",
"containerId": "0",
"type": "FORM_URL",
"name": "Form URL"
},
{
"accountId": "0",
"containerId": "0",
"type": "HTML_ID",
"name": "HTML ID"
},
{
"accountId": "0",
"containerId": "0",
"type": "PAGE_HOSTNAME",
"name": "Page Hostname"
},
{
"accountId": "0",
"containerId": "0",
"type": "PAGE_PATH",
"name": "Page Path"
},
{
"accountId": "0",
"containerId": "0",
"type": "PAGE_URL",
"name": "Page URL"
},
{
"accountId": "0",
"containerId": "0",
"type": "REFERRER",
"name": "Referrer"
}
],
"folder": [
{
"accountId": "0",
"containerId": "0",
"folderId": "1",
"name": "GTM Essentials",
"fingerprint": "0"
}
],
"variable": [
{
"accountId": "0",
"containerId": "0",
"variableId": "1",
"name": "1PC - _fbc",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_fbc"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "2",
"name": "1PC - _fbp",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_fbp"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "3",
"name": "1PC - fbclid",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "fbclid"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "4",
"name": "1PC - _gcl_aw",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_gcl_aw"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "5",
"name": "1PC - _uetmsclkid",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_uetmsclkid"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "6",
"name": "1PC - _ttp",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_ttp"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "7",
"name": "1PC - _twclid",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "_twclid"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "8",
"name": "1PC - li_fat_id",
"type": "k",
"parameter": [
{
"type": "TEMPLATE",
"key": "name",
"value": "li_fat_id"
},
{
"type": "BOOLEAN",
"key": "decodeCookie",
"value": "true"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "17",
"name": "cJS - Traffic Source",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n // cJS - Traffic Source\n //\n // Last-touch traffic source for lead gen and ecommerce conversion tags, returned as one\n // flat snake_case string (google_ads, facebook_ads, google_organic, newsletter_email,\n // referral, direct, ...).\n //\n // Classification mirrors the MTK Attribution engine (resolveTouch): the same click IDs,\n // the same utm_medium values, the same referrer domain lists, and the same fresh-cookie\n // rescue — collapsed to a single string instead of channel + source.\n //\n // An ENTRY is resolved once, from the pageview that brought the visitor in, and carried\n // through the tab in sessionStorage so popup forms and multi-step checkouts on internal\n // pages still report the source that started the visit. A later pageview only replaces\n // the stored entry when it carries a fresh campaign signal in the URL (a click ID or a\n // UTM) or the tab has been idle for longer than the session window — internal navigation\n // never changes attribution, and neither does a mid-funnel bounce through a payment\n // gateway or an OAuth provider.\n\n var STORE_KEY = 'cjs_traffic_source'; // sessionStorage key: {\"v\": \"<source>\", \"t\": <last activity ms>}\n var SESSION_TIMEOUT = 30 * 60 * 1000; // 30 minutes, GA-style — idle longer than this = new entry\n var PAID_SOCIAL_MEDIUM = 'paid_social'; // the utm_medium ad URLs must carry to count as paid social\n\n // Referrer domain lists — same fragments as the MTK engine defaults. A trailing dot means\n // \"this label anywhere in the host\" (google.com, news.google.de); an inner dot means \"this\n // exact domain or a subdomain of it\" (x.com, www.x.com — but never wix.com).\n var SEARCH_DOMAINS = ['google.', 'bing.', 'yahoo.', 'duckduckgo.', 'ecosia.'];\n var SOCIAL_DOMAINS = ['facebook.', 'fb.', 'instagram.', 'linkedin.', 'twitter.', 'x.com', 'youtube.', 'reddit.', 'pinterest.', 'tiktok.', 't.co'];\n\n // utm_source aliases -> the platform name this variable reports. Covers Meta's\n // {{site_source_name}} values (fb / ig / msg / an) recommended in the UTM docs, so a paid\n // Facebook click tagged utm_source=fb returns facebook_ads, not fb_ads.\n var SOURCE_ALIASES = {\n fb: 'facebook', ig: 'instagram', msg: 'messenger', an: 'audience_network',\n x: 'twitter', 'x.com': 'twitter',\n googleads: 'google', adwords: 'google',\n bingads: 'microsoft', bing: 'microsoft'\n };\n\n // ---------------------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------------------\n\n var params = new URLSearchParams(window.location.search);\n function param(key) { return params.get(key) || ''; }\n function lower(s) { return s ? String(s).toLowerCase() : ''; }\n\n // Turn any typed value into a safe snake_case token (\"Facebook Ads\" -> \"facebook_ads\").\n function slug(s) {\n return lower(s).replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');\n }\n\n // Alias lookup, then slug — so utm_source=IG and utm_source=Instagram both give \"instagram\".\n function sourceName(raw) {\n var key = lower(raw);\n if (!key) return '';\n return SOURCE_ALIASES.hasOwnProperty(key) ? SOURCE_ALIASES[key] : slug(key);\n }\n\n // sessionStorage access that degrades to \"no persistence\" in private browsing / blocked storage.\n function readStore() {\n try { var raw = sessionStorage.getItem(STORE_KEY); return raw ? JSON.parse(raw) : null; } catch (e) { return null; }\n }\n function writeStore(value) {\n try { sessionStorage.setItem(STORE_KEY, JSON.stringify({ v: value, t: Date.now() })); } catch (e) {}\n }\n\n // Referrer HOST only — scheme, userinfo, port, and path stripped — so a path or query string\n // containing \"x.com\" or \"google.\" can never be mistaken for the referring domain.\n var referrer = lower(document.referrer);\n var refHost = referrer\n .replace(/^[a-z][a-z0-9+.-]*:\\/\\//, '')\n .split('/')[0]\n .split('@').pop()\n .split(':')[0];\n var selfHost = lower(window.location.hostname);\n\n // A referrer from the site's own hostname is internal navigation, not attribution.\n var hasReferrer = referrer !== '' && refHost !== selfHost;\n\n // Boundary-aware domain match against refHost (see SEARCH_DOMAINS comment for the styles).\n function hostMatches(frag) {\n if (!frag) return false;\n if (frag.charAt(frag.length - 1) === '.') {\n // \"google.\" — label prefix anywhere in the host\n return refHost.indexOf(frag) === 0 || refHost.indexOf('.' + frag) > -1;\n }\n if (frag.indexOf('.') > -1) {\n // \"x.com\" — exact registrable domain or a subdomain of it\n if (refHost === frag) return true;\n var tail = '.' + frag;\n return refHost.length > tail.length && refHost.indexOf(tail) === refHost.length - tail.length;\n }\n return refHost.indexOf(frag) > -1; // plain substring for loose custom entries\n }\n function matchesList(list) {\n for (var i = 0; i < list.length; i++) { if (hostMatches(list[i])) return true; }\n return false;\n }\n\n // The platform name behind a referrer, used for the \"<name>_organic\" buckets. Anything not\n // listed reports its registrable-ish host label (e.g. \"ecosia\" for ecosia.org).\n function referrerName() {\n if (hostMatches('google.')) return 'google';\n if (hostMatches('bing.')) return 'bing';\n if (hostMatches('yahoo.')) return 'yahoo';\n if (hostMatches('duckduckgo.')) return 'duckduckgo';\n if (hostMatches('facebook.') || hostMatches('fb.')) return 'facebook';\n if (hostMatches('instagram.')) return 'instagram';\n if (hostMatches('linkedin.')) return 'linkedin';\n if (hostMatches('twitter.') || hostMatches('x.com') || hostMatches('t.co')) return 'twitter';\n if (hostMatches('youtube.')) return 'youtube';\n if (hostMatches('reddit.')) return 'reddit';\n if (hostMatches('pinterest.')) return 'pinterest';\n if (hostMatches('tiktok.')) return 'tiktok';\n var labels = refHost.replace(/^www\\./, '').split('.');\n return slug(labels.length > 1 ? labels[labels.length - 2] : labels[0]);\n }\n\n // Cookie reader — exact name match, so \"_gcl_aw\" can't be satisfied by \"x_gcl_aw\".\n function readCookie(name) {\n var parts = document.cookie ? document.cookie.split('; ') : [];\n for (var i = 0; i < parts.length; i++) {\n var pair = parts[i].split('=');\n if (pair[0] === name) {\n try { return decodeURIComponent(pair.slice(1).join('=')); } catch (e) { return ''; }\n }\n }\n return '';\n }\n\n // Platform cookies embed the click ID AND its creation time. Only a FRESH cookie — created\n // within the session window — may classify an entry. A stale one just means \"returning\n // visitor\" (these cookies live ~90 days); using it would erase Direct and double-credit ads\n // for months. Returns the click ID, or null.\n function freshClickCookie(name, tsIndex, tsUnit) {\n var raw = readCookie(name);\n if (!raw) return null;\n var parts = raw.split('.');\n var ts = parseInt(parts[tsIndex], 10);\n if (!ts) return null;\n if (tsUnit === 's') ts = ts * 1000;\n var age = Date.now() - ts;\n if (age < 0 || age > SESSION_TIMEOUT) return null;\n return parts.slice(tsIndex + 1).join('.') || null;\n }\n function freshGclid() { return freshClickCookie('_gcl_aw', 1, 's'); } // \"_gcl_aw\" = GCL.{seconds}.{gclid}\n function freshFbclid() { return freshClickCookie('_fbc', 2, 'ms'); } // \"_fbc\" = fb.1.{ms}.{fbclid}\n\n // Does THIS pageview carry a campaign signal — any UTM or any ad-platform click ID? Read from\n // the URL only: cookies outlive the click by weeks and must never look like a fresh arrival.\n function hasCampaignSignal() {\n if (param('utm_source') || param('utm_medium') || param('utm_campaign')) return true;\n return !!(param('gclid') || param('gbraid') || param('wbraid') ||\n param('msclkid') || param('fbclid') || param('ttclid'));\n }\n\n // ---------------------------------------------------------------------------------------\n // Resolver — the MTK engine's rule order, flattened to one string. First match wins.\n // ---------------------------------------------------------------------------------------\n function resolve() {\n var utmSourceRaw = param('utm_source');\n var utmSource = lower(utmSourceRaw);\n var utmMedium = lower(param('utm_medium'));\n\n var gclid = param('gclid');\n var gbraid = param('gbraid'); // iOS web-to-app Google Ads click ID\n var wbraid = param('wbraid'); // iOS app-to-web Google Ads click ID\n var msclkid = param('msclkid');\n var fbclid = param('fbclid');\n var ttclid = param('ttclid');\n\n // 1. Paid Search — any Google / Microsoft click ID, or utm_medium=cpc / paid_search\n // (manual tagging with auto-tagging off, or a click ID stripped by a redirect).\n if (gclid || gbraid || wbraid || msclkid || utmMedium === 'cpc' || utmMedium === 'paid_search') {\n if (msclkid || utmSource === 'bing' || utmSource === 'bingads' || utmSource === 'microsoft') return 'microsoft_ads';\n if (!utmSource || utmSource === 'google' || utmSource === 'googleads' || utmSource === 'adwords') return 'google_ads';\n return sourceName(utmSourceRaw) + '_ads'; // some other paid-search network, tagged by hand\n }\n\n // 2. Paid Social — REQUIRES the utm_medium convention. Meta appends fbclid to organic posts\n // too, so fbclid / _fbc alone can never prove a paid click.\n if (utmMedium === PAID_SOCIAL_MEDIUM) {\n return (sourceName(utmSourceRaw) || 'facebook') + '_ads';\n }\n\n // 3. TikTok Ads — ttclid is paid-only (organic TikTok links don't carry it).\n if (ttclid) return 'tiktok_ads';\n\n // 4. Email — \"<source>_email\" (newsletter_email, klaviyo_email), or plain \"email\" when untagged.\n if (utmMedium === 'email') {\n return utmSource ? sourceName(utmSourceRaw) + '_email' : 'email';\n }\n\n // 5. Any other tagged campaign — \"<source>_<medium>\" (partner_referral, podcast_sponsorship),\n // or just \"<source>\" when there is no medium.\n if (utmSource) {\n return utmMedium ? sourceName(utmSourceRaw) + '_' + slug(utmMedium) : sourceName(utmSourceRaw);\n }\n\n // 6. Untagged arrival with an external referrer.\n if (hasReferrer) {\n if (matchesList(SEARCH_DOMAINS)) {\n // Same-platform upgrade: an ad click FROM google.com whose gclid was lost in transit\n // still set a fresh _gcl_aw — that's Google Ads, not organic.\n if (hostMatches('google.') && freshGclid()) return 'google_ads';\n return referrerName() + '_organic';\n }\n if (matchesList(SOCIAL_DOMAINS) || fbclid) {\n // Same-platform upgrade — but ONLY when the URL carried no fbclid. The Pixel writes _fbc\n // from whichever fbclid it sees, so a fresh _fbc next to an fbclid is just that (possibly\n // organic) click echoed back. With no fbclid in the URL, a fresh _fbc is real evidence of\n // a paid click whose parameter went missing.\n if (!fbclid && (hostMatches('facebook.') || hostMatches('fb.') || hostMatches('instagram.')) && freshFbclid()) {\n return 'facebook_ads';\n }\n // fbclid from a referrer outside the social list (e.g. a Messenger in-app browser) is still Meta.\n return (matchesList(SOCIAL_DOMAINS) ? referrerName() : 'facebook') + '_organic';\n }\n return 'referral'; // some other site we don't bucket\n }\n\n // 7. fbclid with no referrer at all (some in-app browsers strip it) — still an organic Meta click.\n if (fbclid) return 'facebook_organic';\n\n // 8. Cookie rescue — last resort before Direct. A FRESH platform cookie means an ad click just\n // happened but its URL signal never reached us (consent redirect, URL rewrite, tag first\n // firing mid-session). Stale cookies never classify.\n if (freshGclid()) return 'google_ads';\n if (freshFbclid()) return 'facebook_ads';\n\n // 9. Nothing identifying — typed URL, bookmark, app, dark social.\n return 'direct';\n }\n\n // ---------------------------------------------------------------------------------------\n // Entry handling — reuse the stored entry through internal navigation; re-resolve on a fresh\n // campaign signal, after the idle window, or when nothing is stored yet.\n // ---------------------------------------------------------------------------------------\n var stored = readStore();\n var expired = !stored || !stored.t || (Date.now() - stored.t) > SESSION_TIMEOUT;\n\n if (stored && stored.v && !expired && !hasCampaignSignal()) {\n writeStore(stored.v); // touch last-activity, keep the value\n return stored.v;\n }\n\n var value = resolve();\n writeStore(value);\n return value;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "18",
"name": "cJS - Ad Placement",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n // Captures utm_placement from URL on first pageview, persists via sessionStorage.\n // Handles both Meta placements (e.g. \"Audience_Network_Native\", \"Facebook_Mobile_Feed\")\n // and Google Ads placements (e.g. \"g_1t1\" for top-of-page search, \"gmb_\" for Business Profile,\n // \"d_\" for Display Network). The variable doesn't care which platform set the value —\n // utm_source already tells you that. This just captures whatever placement was passed.\n \n var STORAGE_KEY = 'ad_placement';\n \n try {\n // First, check if utm_placement is in the current URL.\n // If yes, this is the freshest signal — overwrite anything stored.\n var urlParams = new URLSearchParams(window.location.search);\n var placementFromUrl = urlParams.get('utm_placement');\n \n if (placementFromUrl) {\n try { sessionStorage.setItem(STORAGE_KEY, placementFromUrl); } catch(e) {}\n return placementFromUrl;\n }\n \n // No utm_placement in current URL — fall back to whatever we stored\n // earlier in this session (e.g. from the original landing page).\n try {\n var stored = sessionStorage.getItem(STORAGE_KEY);\n if (stored) return stored;\n } catch(e) {}\n \n // No URL value, no stored value — return undefined.\n // GA4 will simply omit the parameter rather than send an empty string.\n return undefined;\n \n } catch (e) {\n // URLSearchParams unavailable (very old browsers) or other failure\n return undefined;\n }\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "19",
"name": "cJS - Page Title",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n return document.title;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "20",
"name": "cJS - Post Title",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n var el = document.querySelector('.entry-title, h1.entry-title, h1');\n if (el && el.textContent) return el.textContent.trim();\n var og = document.querySelector('meta[property=\"og:title\"]');\n return og ? og.getAttribute('content') : undefined;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "21",
"name": "cJS - Post ID",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n var m = (document.body.className || '').match(/(?:postid|page-id)-(\\d+)/);\n return m ? m[1] : undefined;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "22",
"name": "cJS - Form ID",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n var f = document.querySelector('form[id]');\n return f ? f.id : undefined;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "23",
"name": "DLV - gtm.uniqueEventId",
"type": "v",
"parameter": [
{
"type": "INTEGER",
"key": "dataLayerVersion",
"value": "2"
},
{
"type": "BOOLEAN",
"key": "setDefaultValue",
"value": "false"
},
{
"type": "TEMPLATE",
"key": "name",
"value": "gtm.uniqueEventId"
}
],
"fingerprint": "0",
"parentFolderId": "1"
},
{
"accountId": "0",
"containerId": "0",
"variableId": "24",
"name": "cJS - Custom Event ID",
"type": "jsm",
"parameter": [
{
"type": "TEMPLATE",
"key": "javascript",
"value": "function() {\n var id = {{DLV - gtm.uniqueEventId}}; // Page-local counter — the cache key\n\n if (window.customEventIdKey !== id) {\n window.customEventIdKey = id;\n // Globally unique value — this is what actually goes to Meta\n window.customEventId = (new Date()).getTime() + '.' +\n Math.random().toString(36).substring(2, 10);\n }\n\n return window.customEventId;\n}"
}
],
"fingerprint": "0",
"parentFolderId": "1"
}
],
"fingerprint": "0"
}
}