-
-
Save dillansimmons/a2c1ebad5788dc2a2d9cb45669d9396e to your computer and use it in GitHub Desktop.
// 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
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.
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.
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.
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();
}
}
});
}
})();
Dillan, you're amazing! It worked! Thanks for your fast reply and your support. You helped me a lot. :-)
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
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¶m=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];
});
}
})();
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.
Thanks !