This Google Tag Manager (GTM) Custom Template sets a first-party cookie (and optionally localStorage) to capture and persist attribution data across pages and sessions. It captures UTM parameters and advertising Click IDs, formats them into a JSON object, and stores it for reuse in your tags, analytics tools, or backend systems. Optionally, it can push the same data into the dataLayer for GA4 and GTM workflows.
Built by Daniel Perry-Reed – analytics specialist at Data to Value.
- Captures UTM parameters:
utm_source,utm_medium,utm_campaign,utm_content,utm_term,utm_id,utm_source_platform,utm_creative_format, andutm_marketing_tactic
- Captures common ad click IDs
gclid,fbclidandmsclkid- Optionally add your own custom defined IDs
- Captures referrer info
referrer.fullandreferrer.domain - Stores attribution data in a first-party cookie
- Optionally stores attribution in localStorage
- Automatically syncs between cookie and localStorage if one is missing
- Optionally pushes attribution data to the dataLayer as a GTM event
- Optionally URL-encode all values
- Optioanlly logging all actions to the browser console
| Version | Changes |
|---|---|
| v0.1 | - Initial release with support for core UTM parameters (utm_source, utm_medium, utm_campaign, utm_content, and utm_term) - Captured core click IDs ( gclid, fbclid, msclkid) with option to add in custom list - Optional localStorage backup with cookie-localStorage sync functionality - Advanced options for overriding cookie settings - Optional browser console logs |
| v0.2 | - Added support for additional UTM parameters (utm_id, utm_source_platform, utm_creative_format, utm_marketing_tactic) - Added optional DataLayer push feature (with configurable event name) |
| v0.3 (current) | - Added support for capturing referrer info (referrer.full and referrer.domain) - Added optional attribution update on referrers with no UTMs or Click IDs in the URL |
| future plans | - Optional custom mapping for traffic source/medium by click ID - TBC, let me know! |
This is the fastest way to get started. It includes the custom template, tag, some dataLayer variables, and dataLayer trigger.
-
Download the container file
📄 Downloadgtm_attr_container.json -
Import into GTM
- Go to GTM > Admin > Import Container
- Upload the file
- Choose your workspace
- Select Merge and Rename conflicting tags/variables/templates
-
Review and publish
- Confirm the tag fires as expected
- Publish your container
- Go to Templates > New
- Paste in the code from
gtm_attr_template.js
| Field Name | Type | Description |
|---|---|---|
cookieName |
Text | Name of the cookie (default: gtm_attr) |
cookieDomain |
Text | Domain for the cookie (default: auto) |
cookieHours |
Text | Cookie lifetime in hours (default: 720) |
extraClickIds |
Text | Comma-separated custom click ID keys |
encodeValues |
Checkbox | URL-encode attribution values |
enableLocalStorage |
Checkbox | Store attribution in localStorage |
pushToDataLayer |
Checkbox | Push attribution object to dataLayer as an event |
dataLayerEventName |
Text | Event name for DataLayer push (default: gtm_attr) |
overrideOnNewReferrerDomain |
Checkbox | If enabled, JSON resets on new referrer domain (unless ignored) |
ignoreDomains |
Text | Comma-separated list of domains to ignore (no update if referrer matches) |
logMessages |
Checkbox | Enable console logging for debugging |
Ensure your template requests:
Set a cookieandReads cookie value(s)(any)Access local storage(read/write for keygtm_attr)Access global variables(dataLayer read/write)getQueryParametersaccess_globalsfordataLayer(read/write)Log to console(always log)Reads URL(any)Reads Referrer URL(any)
- Go to Tags > New
- Choose your custom template
- Set the trigger to All Pages or an appropriate consent-based trigger
- When the tag fires:
- If cookie is missing but localStorage exists, sync from localStorage to cookie
- If localStorage is missing but cookie exists, sync from cookie to localStorage
- This ensures attribution continuity even if cookies are cleared while localStorage remains intact
Cookie / localStorage value:
{
"utm_source": "google",
"utm_medium": "cpc",
"utm_campaign": "spring_sale",
"utm_id": "12345",
"utm_source_platform": "google_ads",
"utm_creative_format": "responsive",
"utm_marketing_tactic": "remarketing",
"click_id": {
"type": "gclid",
"value": "abc123"
},
"referrer": {
"full": "https://example.com/page",
"domain": "example.com"
}
}DataLayer event (if enabled):
dataLayer.push({
event: "gtm_attr",
attribution: {
...same as above...
}
});Built and maintained by myself and the team at Data to Value — your data activation partner helping marketing and RevOps teams transform data into predictable revenue and growth.
MIT