- note that you shouldn't exclude all query parameters by default, since Google Analytics needs some for traffic attribution to work (gclid and anything with utm_). So just sending
document.location.pathname
will break attribution to Google Ads and own campaign links with UTM parameters.
- For giving you a solution I will first differentiate between GTM and gtag.js because they have different implementation methods for adding a custom page URL.
- Then, we have to differentiate between filtering out all query params or filtering out query params we know the name of
- Finally I’ll explain how to add that to either GTM or gtag.js
filtering out all query params
- we filter out all the params except of the ones that are crucial for google analytics functioning (
gclid
, anything with utm_
and gtm_debug
)
- update the includeStrings array to keep any other parameters
function cleanPageLocation() {
// define parameters to keep if available
var includeStrings = [
"gclid",
"utm_",
"gtm_debug"
];
var addressString = new URL(document.location);
var queryString = addressString.search;
/* check if query string holds any parameters, otherwise just return the url without them */
if (queryString.indexOf("?") != -1) {
// transpile ES2016 => ES2015
var _defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
/* https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript */
var getQueryParamsFromURL = function getQueryParamsFromURL() {
var match,
search = /([^&=]+)=?([^&]*)/g,
decode = function decode(s) {
return decodeURIComponent(s);
},
query = addressString.search.substring(1);
var urlParams = {};
while ((match = search.exec(query))) {
urlParams[decode(match[1])] = decode(match[2]);
}
return urlParams;
};
var filterParamsFromList = function filterParamsFromList(obj, list) {
var urlParamKeysFinal = [];
var urlParamKeys = Object.keys(obj);
/* test each param for availability and create array with final keys */
for (var i = 0; i < list.length; i++) {
urlParamKeysFinal.push(
urlParamKeys.filter(function (key) {
return key.includes(list[i]);
})
);
}
// merge all keys into one list
/* https://stackoverflow.com/questions/10865025/merge-flatten-an-array-of-arrays */
urlParamKeysFinal = [].concat.apply([], urlParamKeysFinal);
return urlParamKeysFinal.reduce(function (cur, key) {
return Object.assign(cur, _defineProperty({}, key, obj[key]));
}, {});
};
// create param object from query string
var urlParams = getQueryParamsFromURL(); /* Create filtered query string */
queryString = new URLSearchParams(
// remove any non-matching keys from param object
filterParamsFromList(urlParams, includeStrings)
).toString();
// add ? to querystring unless it's empty
if (queryString != "") queryString = "?" + queryString;
}
// return cleaned URL
return addressString.origin + addressString.pathname + queryString;
}
}
filtering out query params we know the name of
- update the
excludeStrings
array to define the parameter names you want to keep
function cleanPageLocation() {
// define parameters to keep if available
var includeStrings = [
"gclid",
"utm_",
"gtm_debug"
];
var addressString = new URL(document.location);
var queryString = addressString.search;
/* check if query string holds any parameters, otherwise just return the url without them */
if (queryString.indexOf("?") != -1) {
// transpile ES2016 => ES2015
var _defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
/* https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript */
var getQueryParamsFromURL = function getQueryParamsFromURL() {
var match,
search = /([^&=]+)=?([^&]*)/g,
decode = function decode(s) {
return decodeURIComponent(s);
},
query = addressString.search.substring(1);
var urlParams = {};
while ((match = search.exec(query))) {
urlParams[decode(match[1])] = decode(match[2]);
}
return urlParams;
};
var filterParamsFromList = function filterParamsFromList(obj, list) {
var urlParamKeysFinal = [];
var urlParamKeys = Object.keys(obj);
/* test each param for availability and create array with final keys */
for (var i = 0; i < list.length; i++) {
urlParamKeysFinal.push(
urlParamKeys.filter(function (key) {
return key.includes(list[i]);
})
);
}
// merge all keys into one list
/* https://stackoverflow.com/questions/10865025/merge-
flatten-an-array-of-arrays */
urlParamKeysFinal = [].concat.apply([], urlParamKeysFinal);
return urlParamKeysFinal.reduce(function (cur, key) {
return Object.assign(cur, _defineProperty({}, key, obj[key]));
}, {});
};
// create param object from query string
var urlParams = getQueryParamsFromURL(); // Create filtered query string
queryString = new URLSearchParams(
// remove any non-matching keys from param object
filterParamsFromList(urlParams, includeStrings)
).toString();
// add ? to querystring unless it's empty
if (queryString != "") queryString = "?" + queryString;
}
// return cleaned URL
return addressString.origin + addressString.pathname + queryString;
}
Exclude query parameters in GA4 for gtag.js
- For gtag.js, the cleanPageLocation() function needs to be added directly to the GA4 snippet and assigned to the page_location parameter.
- define the function before the GA4 snippet in a
<script>...</script>
tag
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=YOUR-ID-HERE">
</script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'YOUR-ID-HERE', {
/* below we let the function return the URL without query parameter */
'page_location': cleanPageLocation(),
});
</script>
Exclude query parameters in GA4 for GTM
- for GTM, a custom JS variable needs to be created to contain the cleanPageLocation() function and then added as the value to the page_location field in the GA4 configuration tag.
- note however that in Google Tag Manager, the custom JavaScript variable that contains the cleanPageLocation function needs to be anonymous. This means that instead of explicitly naming the function like in the gtag.js solution, you will define the function as an anonymous function expression.
- Here's an example of how the first line of the cleanPageLocation() function would look like as an anonymous function:
function() {
- afterwards add the JS variable as value to the GA4 config tags field
page_location

more info: https://bluerivermountains.com/en/ga4-query-parameter-exclusion