Problem
In most websites, when a user lands on a page with UTM parameters (like utm_source, utm_campaign, etc.) and then clicks around to other internal pages, those UTM parameters vanish from the URL. This breaks attribution and makes it harder to know which channel or campaign actually drove the conversion, especially for forms or events that fire on later pages.
Solution
I implemented a simple yet powerful JavaScript code snippet that automatically appends UTM parameters to all internal links on the website, so when a user navigates from one page to another, the UTM parameters follow them like a clingy ex.
✅ Works across all pages
✅ Preserves attribution
✅ Doesn’t break existing links
I injected this code via Google Tag Manager, using a DOM Ready trigger, so it executes after the page loads and updates all relevant links dynamically.
Implementation
-
Set up a Custom HTML tag in GTM.
(function() {
var params = new URLSearchParams(window.location.search);
var utmKeys = [“utm_source”, “utm_medium”, “utm_campaign”, “utm_term”];
var hasUtm = utmKeys.some(function(k) { return params.has(k); });
if (!hasUtm) return;var utmValues = {};
utmKeys.forEach(function(k) {
if (params.has(k)) {
utmValues[k] = params.get(k);
}
});var links = document.querySelectorAll(“a[href]”);
links.forEach(function(link) {
var href = link.getAttribute(“href”).trim();if (
href.charAt(0) === “#” ||
href.indexOf(“javascript:”) === 0 ||
href.indexOf(“mailto:”) === 0 ||
href.indexOf(“tel:”) === 0
) {
return;
}try {
// 4. Parse the link, using the page as base for relative URLs
var url = new URL(href, window.location.href);Object.keys(utmValues).forEach(function(key) {
url.searchParams.set(key, utmValues[key]);
});var newHref = url.href;
if (newHref.indexOf(window.location.origin) === 0) {
newHref = newHref.slice(window.location.origin.length);
}link.setAttribute(“href”, newHref);
} catch (e) {
console.warn(“Failed to append UTM to”, href, e);
}
});
})(); -
Triggered on All Pages – DOM Ready.
-
Published and tested using GTM’s Preview Mode + Real-time Analytics Debugging.
Results
- UTM parameters are now preserved across the full user session.
- Conversion attribution is more accurate.
- Better insights in GA4 / Meta / Google Ads reports.