Skip to content

Instantly share code, notes, and snippets.

@dillansimmons
Last active January 11, 2024 18:00
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save dillansimmons/a2c1ebad5788dc2a2d9cb45669d9396e to your computer and use it in GitHub Desktop.
Save dillansimmons/a2c1ebad5788dc2a2d9cb45669d9396e to your computer and use it in GitHub Desktop.
Pass current UTMS to in page links Javascript
// JS for grabbing utm params and parsing into url
var getRefQueryParam = function() {
var temp = {};
document.location.search.replace(/\??(?:([^=]+)=([^&]*)&?)/g, function() {
var decode = function(s) {
return decodeURIComponent(s.split("+").join(" "));
};
temp[decode(arguments[1])] = decode(arguments[2]);
});
return temp;
};
// Get all the UTM parameters before the page finishes rendering
//Variables
var utmParamQueryString = '',
utmParamQueryStringTrimmed = '',
utm_source = '',
utm_medium = '',
utm_content = '',
utm_campaign = '',
(function() {
utm_source = getRefQueryParam("utm_source");
utm_medium = getRefQueryParam("utm_medium");
utm_content = getRefQueryParam("utm_content");
utm_campaign = getRefQueryParam("utm_campaign");
if (utm_source) {
utmParamQueryString += '&utm_source=' + utm_source;
}
if (utm_medium) {
utmParamQueryString += '&utm_medium=' + utm_medium;
}
if (utm_content) {
utmParamQueryString += '&utm_content=' + utm_content;
}
if (utm_campaign) {
utmParamQueryString += '&utm_campaign=' + utm_campaign;
}
// if there are utm values add them all up
if (utmParamQueryString.length > 0) {
utmParamQueryString = utmParamQueryString.substring(1);
utmParamQueryStringTrimmed = utmParamQueryString;
utmParamQueryString = '?' + utmParamQueryString;
}
})();
// Grab all links you want to target - change the class to whatever you are using i.e .utm-passthrough
var navlinks = document.querySelectorAll('a.utm-passthrough');
// Loop through all links
Array.prototype.forEach.call(links, function (link) {
// Take the href and append the UTM parameters
link.href += utmParamQueryString;
});
@harberg
Copy link

harberg commented Nov 30, 2017

function getRefQueryParam(name) {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

var utmParamQueryString = '',
    utmParamQueryStringTrimmed = '',
    utm_source = '',
    utm_medium = '',
    utm_content = '',
    utm_campaign = '',
    utm_term = '';

(function() {
    utm_source = getRefQueryParam("utm_source");
    utm_medium = getRefQueryParam("utm_medium");
    utm_content = getRefQueryParam("utm_content");
    utm_campaign = getRefQueryParam("utm_campaign");
    utm_term = getRefQueryParam("utm_term");

    if (utm_source) {
        utmParamQueryString += '&utm_source=' + utm_source;
    }
    if (utm_medium) {
        utmParamQueryString += '&utm_medium=' + utm_medium;
    }
    if (utm_content) {
        utmParamQueryString += '&utm_content=' + utm_content;
    }
    if (utm_campaign) {
        utmParamQueryString += '&utm_campaign=' + utm_campaign;
    }
    if (utm_term) {
        utmParamQueryString += '&utm_term=' + utm_term;
    }

    if(utmParamQueryString.length > 0) {
        utmParamQueryString = utmParamQueryString.substring(1);
        utmParamQueryStringTrimmed = utmParamQueryString;
        utmParamQueryString = '?' + utmParamQueryString;
    }
})();

var navLinks = document.querySelectorAll('section.tilesContainer a');

navLinks.forEach(function(item) {
    item.href += utmParamQueryString;
});

@harberg
Copy link

harberg commented Nov 30, 2017

The getRefQueryParam() wasn't working so I made a little tweak. Added in UTM_Term as well.
Dropped the ball on the comments.

@deanmcpherson
Copy link

function getRefQueryParam(name) {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

var utmParamQueryString = '',
    utmParamQueryStringTrimmed = '',
    utm_source = '',
    utm_medium = '',
    utm_content = '',
    utm_campaign = '',
    utm_term = '';

(function() {
    utm_source = getRefQueryParam("utm_source");
    utm_medium = getRefQueryParam("utm_medium");
    utm_content = getRefQueryParam("utm_content");
    utm_campaign = getRefQueryParam("utm_campaign");
    utm_term = getRefQueryParam("utm_term");

    if (utm_source) {
        utmParamQueryString += '&utm_source=' + utm_source;
    }
    if (utm_medium) {
        utmParamQueryString += '&utm_medium=' + utm_medium;
    }
    if (utm_content) {
        utmParamQueryString += '&utm_content=' + utm_content;
    }
    if (utm_campaign) {
        utmParamQueryString += '&utm_campaign=' + utm_campaign;
    }
    if (utm_term) {
        utmParamQueryString += '&utm_term=' + utm_term;
    }

    if(utmParamQueryString.length > 0) {
        utmParamQueryString = utmParamQueryString.substring(1);
        utmParamQueryStringTrimmed = utmParamQueryString;
        utmParamQueryString = utmParamQueryString;
    }
    if (!utmParamQueryString) return;
    var navLinks = document.querySelectorAll('a');

    navLinks.forEach(function(item) {
      if (item.href.indexOf('/') === 0 || item.href.indexOf(location.host) !== -1) {
        if (item.href.indexOf('?') === -1) {
            item.href += '?';
        } else {
          item.href += '&';
        }
        item.href += utmParamQueryString;
      }
    });
})();

Modified to not interfere with existing query params, and only apply to links on the same domain.

@fabianrie
Copy link

Which specific changes do I have to make this script work for my domain?
My goal is to add the original utm parameters only to the following domain, which is embeded 6x on my initial landingpage:
testsurvey.de

So I want to send the traffic to: test.de/?utm_source=facebook?utm_campaign=feed and add the utm parameters to testsurvey.de/?utm_source=facebook?utm_campaign=feed

Maybe you can help me out with that? My coding expertise is not good enough to modify this script. Thanks in advance!

function getRefQueryParam(name) {
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    var results = regex.exec(location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
};

var utmParamQueryString = '',
    utmParamQueryStringTrimmed = '',
    utm_source = '',
    utm_medium = '',
    utm_content = '',
    utm_campaign = '',
    utm_term = '';

(function() {
    utm_source = getRefQueryParam("utm_source");
    utm_medium = getRefQueryParam("utm_medium");
    utm_content = getRefQueryParam("utm_content");
    utm_campaign = getRefQueryParam("utm_campaign");
    utm_term = getRefQueryParam("utm_term");

    if (utm_source) {
        utmParamQueryString += '&utm_source=' + utm_source;
    }
    if (utm_medium) {
        utmParamQueryString += '&utm_medium=' + utm_medium;
    }
    if (utm_content) {
        utmParamQueryString += '&utm_content=' + utm_content;
    }
    if (utm_campaign) {
        utmParamQueryString += '&utm_campaign=' + utm_campaign;
    }
    if (utm_term) {
        utmParamQueryString += '&utm_term=' + utm_term;
    }

    if(utmParamQueryString.length > 0) {
        utmParamQueryString = utmParamQueryString.substring(1);
        utmParamQueryStringTrimmed = utmParamQueryString;
        utmParamQueryString = utmParamQueryString;
    }
    if (!utmParamQueryString) return;
    var navLinks = document.querySelectorAll('a');

    navLinks.forEach(function(item) {
      if (item.href.indexOf('/') === 0 || item.href.indexOf(location.host) !== -1) {
        if (item.href.indexOf('?') === -1) {
            item.href += '?';
        } else {
          item.href += '&';
        }
        item.href += utmParamQueryString;
      }
    });
})();

Modified to not interfere with existing query params, and only apply to links on the same domain.

@dillansimmons
Copy link
Author

dillansimmons commented Oct 16, 2019

Hey been a while since I wrote this,

To get it to work in your case you would need to change this line if (item.href.indexOf('/') === 0 || item.href.indexOf(location.host) !== -1) { to if (item.href.indexOf('test.de') !== -1) {. This tells the code to only run on links who have the url test.de.

Also... below is an updated version. There is a new JS interface that will do most of the heavy lifting now: https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams, it does not work in IE though, so if that is a requirement it would not work. The code below is a more concise version that would work for you, also added some comments.

(function() {
    // use URLSerachParams to get strings <- does not work in Internet Explorer
    const utmParamQueryString = new URLSearchParams(window.location.search);
    if (utmParamQueryString) {
        // get all the links on the page
        var navLinks = document.querySelectorAll('a');
        navLinks.forEach(function(item) {
        // if the links hrefs contain test.de then run
        if (item.href.indexOf('test.de') !== -1) {
            // if the link href does NOT have query strings add query strings as is
            if (item.href.indexOf('?') === -1) {
                item.href += '?' + utmParamQueryString.toString();
            // otherwise append the query strings with a &
            } else {
            item.href += '&' + utmParamQueryString.toString();
            }
        }
        });
    }
})();

@fabianrie
Copy link

Dillan, you're amazing! It worked! Thanks for your fast reply and your support. You helped me a lot. :-)

@khanhicetea
Copy link

khanhicetea commented Nov 7, 2019

This script will pass only utm_

(function() {
    const params = new URLSearchParams(window.location.search);
    const utm_params = [];
    params.forEach(function(value, key) {
        if (key.startsWith('utm_')) {
            utm_params.push(key+'='+value)
        }
    })
    utm_search = utm_params.join('&');
    if (!!utm_search) {
        document.querySelectorAll('a[href]').forEach(function(ele, idx) {
            ele.href = ele.href + (ele.href.indexOf('?') === -1 ? '?' : '&') + utm_search;
        });
    }
})();

You can add if (ele.href.indexOf('test.de') !== -1) { if you want

@plh4
Copy link

plh4 commented Jul 23, 2022

Thanks for the great work.

I have one question. What do I have to change to have the utm-parameters first?

So for example

https://www.test.org/?param=12345

should change to:

https://www.test.org/?utm_source=xxxx&utm_campaign=abc&param=12345

UPDATE:
It works like that:

(function() {
const params = new URLSearchParams(window.location.search);
const utm_params = [];
params.forEach(function(value, key) {
if (key.startsWith('utm_')) {
utm_params.push(key+'='+value)
}
})
utm_params_string = utm_params.join('&');
var urlArray = [];
let url = "";
if (!!utm_params_string) {
document.querySelectorAll('a[href]').forEach(function(ele, idx) {
url=ele.href;
urlArray=url.split("?");
ele.href = urlArray[0] + '?' + utm_params_string + '&' + urlArray[1];
});
}
})();

@mglinski
Copy link

mglinski commented Jan 11, 2024

I took the examples of @khanhicetea and @dillansimmons above and made a hybrid version using URL and URLSearchParams classes for all of the heavy lifting. This will not work on older browsers.

This will propagate any query param starting with utm_ into all <a href="..." /> tags on the current page, taking care to follow the following rules:

  • No other query params will be injected except ones starting with utm_
  • Only links with the same exact domain name will have utm params injected
  • If a link has existing UTM params already, this will skip those links and not clobber existing UTM params
  • Existing query params in each link will be preserved
(function () {
    // use URLSerachParams to get strings <- does not work in Internet Explorer
    let deleteParams = [];
    const utmParamQueryString = new URLSearchParams(window.location.search);
    utmParamQueryString.forEach(function (value, key) {
        if (!key.startsWith("utm_")) deleteParams.push(key);
    });
    for (var key in deleteParams) utmParamQueryString.delete(key);
    if (utmParamQueryString) {
        // get all the links on the page
        document.querySelectorAll("a").forEach(function (item) {
            const checkUrl = new URL(item.href);
            // if the links hrefs are not navigating to the same domain, then skip processing them
            if (checkUrl.host === location.host) {
                let doNotProcess = false;
                const linkSearchParams = new URLSearchParams(checkUrl.search);
                linkSearchParams.forEach(function (value, key) {
                    if (key.startsWith("utm_")) doNotProcess = true;
                });
                if (doNotProcess) return;
                checkUrl.search = new URLSearchParams({
                    ...Object.fromEntries(utmParamQueryString),
                    ...Object.fromEntries(linkSearchParams),
                });
                item.href = checkUrl.href;
            }
        });
    }
})();

Hopefully this saves someone time in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment