3

In the dashboard of the new GA4, if I go to Engagement, Page and Screens, then press Page path and screen class I see repeated urls with query parameters with "?"

example.com/?utm_source=...
example.com/

I would like to ask how to unify the page paths

marcori
  • 45
  • 1
  • 6

3 Answers3

2

Query parameter removal with App + Web is a bit different because of the automatic pageview tracking. If you need to remove parameters from your page paths, you can use the page_location field in your Configuration tag in GTM. Keep in mind that there are no filters or view settings to strip query parameters in the Google Analytics interface as we saw for Universal Analytics.

i.e. If you want to remove all query parameters from your page path, we'll use the same method but a different Custom Javascript Variable.

In a new Custom Javascript variable paste the following:

function() {
  return document.location.hostname + document.location.pathname;
}

https://www.bounteous.com/insights/2020/05/15/excluding-url-query-parameters-google-analytics/

Michele Pisani
  • 13,567
  • 3
  • 25
  • 42
2

You can use the config object in your measurement code to override the location string that is reported. You should see a line of code that goes like gtag('config', '...your id...') or gtag('config', '...your id...', { /* some config */ }). You need to either add the 3rd config parameter, or if it is already there you need to add a new attribute into it, so your code should look something like this after all:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=...your id..."></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', '...your id...', {
    'page_location': location.protocol + '//' + location.host + location.pathname,
    /* other options if you have anything else */
  });
</script>

Please note that this will remove all URL parameters so everything after the ?. If you only need to remove some, you need to implement a bit more logic and set page_location to the modified URL with only the unwanted parameters removed.

Bence Szalai
  • 768
  • 8
  • 20
0
  • 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 Settings for GA4 param exlusion in config tag

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