How do I remove URL params from getting pushed to GA4 through GTM? I have tried many solutions but none seem to be working.
Which key in "Fields to Set" do I need to use so GTM replaces the url query param from all dimensions like page_path, page_location, path_referrer?
This article has been my life saver when dealing with URL params in GA4, but please use my experience and avoid the mistake of applying the script directly to page_location.
page_location is what I call a technical dimension that GA4 uses to sort referring websites according to its internal rules and do any other GA4 things. Remove URL params from page_location using GTM, and you'll stop seeing all channels, reliant on UTMs—so paid search, display, paid social, email etc (provided you use UTMs, of course). Don't forget: in this case, you remove the URL params in GTM before they get in GA, so if GTM strips params out, GA doesn't see them.
To illustrate my mistake, this is how my GA4 configuration tag in GTM looked like initially:
Bad idea. Don't touch page_location.
The best approach is to just create your own dimension which you would use to store 'clean' URLs, say, page_URI. The reason: you stop relying on GA built-in dimensions that (potentially) are prone to change and you create something of your own that you will have control over and can add to any event as a dimension.
Below is my version of the script in GTM, deployed as a Custom Javascript Variable:
function() {
var params = ['hash', 'email', 'utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term', 'gclid', 'fbclid', 'mc_cid', 'mc_eid', 'msclkid']; //Add URL params to be excluded from page URI
var a = document.createElement('a');
var param,
qps,
iop,
ioe,
i;
a.href = {{Page URL}};
if (a.search) {
qps = '&' + a.search.replace('?', '') + '&';
for (i = 0; i < params.length; i++) {
param = params[i];
iop = qps.indexOf('&' + param + '=');
if(iop > -1) {
ioe = qps.indexOf('&', iop + 1);
qps = qps.slice(0, iop) + qps.slice(ioe, qps.length);
}
}
a.search = qps.slice(1, qps.length - 1);
}
return a.href;
}
Two things to mention about the code:
List all params you want to strip out in the array params;
a.href = {{Page URL}} - the code makes use of GTM's built-in variable Page URL (hence double curly brackets) that captures the full URL (without hostname, though). If you feel fancy, you can replace it with plain JS.
So the code above now populates the GTM field/GA4 dimension page_URI in the main configuration tag and any other tags, where I think having a clean URI is useful:
I do realize that this approach uses up one GA4 dimension, but it's a price I'm willing to pay to have a clean URL in the absence of a better solution.
In the GA4 tag in GTM try to set page_location as Field to Set and a Custom JavaScript Variable as value with this definition:
function(){
return document.location.hostname + document.location.pathname;
}
i.e. (note: App+Web is old name of GA4):
You can also use the following JavaScript in the custom JavaScript variable instead of the custom JavaScript mentioned above.
In this custom JavaScript instead of creating a new anchor element, we simply are taking the full page URL and then using the JavaScript's in-built URL() method to convert it to a proper URL that can be programmatically managed and then manage it according to the need.
I'm sharing my script below:
Step 1
Create a custom JavaScript variable inside your GTM and add the following JavaScript code into it.
function() {
// Set the array with the list of query string you would like to remove being shown up in Google Analytics 4
var excuded_query_params = [
'add',
'the',
'query',
'strings',
'you',
'would',
'like',
'to',
'be',
'removed',
'from',
'GA4',
'analytics',
'report'
]
// Get the full Page URL from GTM in-build variables
var page_url_string = {{Page URL}}
// Convert the received URL from string format to URL format
var page_url = new URL( page_url_string )
var page_url_copy = new URL( page_url_string )
// Loop through the query parameters in the URL and if there is any query param which is in the excluded list,
// remove that from the full URL
page_url_copy.searchParams.forEach( function(param_value, param_name) {
if( excuded_query_params.includes( param_name ) ) {
page_url.searchParams.delete( param_name )
}
} )
// Return the final URL
return page_url.toString()
}
Please Note: as we are going to replace the value of page_location a default GA4 variable's data - it is highly recommended that you do not remove the utm_ query parameters from the URL as GA4 reports use that data internally and that may lead to report breaking. So, it's best that you do not remove query parameters like utm_souyrce, utm_campaign etc.
Step 2
Inside your GA4 Configuration Tag, click on Fields to Set and add a new field with the Field Name set as page_location and value set as this custom JavaScript variable.
Step 3
Now it's time to preview inside GTM and deeply.
I am using the sample code from https://developers.google.com/analytics/devguides/reporting/core/v4/quickstart/service-php, and printResults is failing because $dimensionHeaders and $dimensions are null
Also, it seems to only work if "ga:" is prepended to the view ID provided by google analytics admin\view\view settings\view ID. Is that correct, or am I using the wrong view ID?
Yes, the correct View ID is what the Google Analytics admin interface is in:
Admin --> View --> View settings --> View ID
Like this:
Google's sample code is missing this key bit in getReport() underneath the line: $request = new Google_Service_AnalyticsReporting_ReportRequest();
//Create the Dimensions object.
$browser = new Google_Service_AnalyticsReporting_Dimension();
$browser->setName("ga:browser");
$request->setDimensions(array($browser));
I tried to migrate from react navigation deeplinks to firebase dynamic linking using this library (react-native-firebase).
I have set up everthing and links are being generated and received on the app. However, is there any way to extract the params sent in the link properly using this library?. Currenty this is my code for handling received link:
handleDynamicLink = () => {
firebase
.links()
.getInitialLink()
.then((url) => {
console.tron.log('link is ', url);
})
.catch((error) => {
console.tron.log(error);
});
};
The url received is
https://links.dev.customdomain.in/?link=products%2F1122
I want to extract the product id 1122 from the url. The only way for me right now is to parse the string and manually extract the relevant params. Unlike in react navigation deeplinks where I used to specify the path, like
Product: {
screen: Product,
path: 'customdomain/products/:slug',
},
Where the slug or id data used to pass as navigation param in the respective screen. Am I missing something? How can I pass mutliple params this way?
Point 2 in this link here says:
The response contains the URL string only.
This means that the firebase.links().getInitialLink() method does not return query parameters, at least as at the time of writing this (v5.5.5). To add your paramaters, you should use a URL with your query param as part of the URL. What I mean is this
Use https://links.dev.customdomain.in/link/products/1122
and use Regex to extract the product id which is of interest to you. This is what works for me and I hope it helps.
I want to send an email with a content related to my data such as in following piece of code I found on Datasource script of Google AppMaker Project Tracker template. But I don't understand how it works. How that data.modifiedBy reflect to the record in my datasource?
Any help from the floors? Thanks ..
Look at the Notifications server side script in the template.
It has method notifyAboutItemChanges_ which is passing the data to this record.
function notifyAboutItemChanges_(changes) {
var settings = getAppSettingsRecord_()[0];
if (!settings.EnableEmailNotifications) {
return;
}
var data = {
appUrl: settings.AppUrl,
itemType: changes[0].Type,
itemKey: changes[0]._key,
itemName: changes[0].Name,
modifiedBy: changes[0].ModifiedBy,
changes: changes
};
// Email subject.
var subjectTemplate =
HtmlService.createTemplate(settings.NotificationEmailSubject);
}
This function is passing this data to your settings record.
So no magic here :) You need to pass the data to your record which will be replaced at run time with the values.
For more details on Email refer this sample app.
I am trying to pass some query params to my http function in Firebase in a secure way. My params are not really sensitive like passwords, etc, they are some booleans, etc that determines logic server side.
When I try a simple <form> with method GET or PUT the res.query shows the values not when I use POST.
<form id="form" action="https://us-central1-***.cloudfunctions.net/myfuncName"
method="post">
<input type="text" name="id" value="test">
</form>
I submit the form in Javascript by
this.getElementById("form").submit();
in my function I have :
function(req, res) {
const param = req.query;
console.log('query param is ' , param); //{} when form method is POST
}
I expect to be able to get id from res.query in my function but I get null {}. If I change method to GET or PUT then I see {id:test}.
Any suggestion on enhancing the security of this would be appreciate too. Thanks.
res.query allows you to get parameters coming from the query string of a request. A POST request doesn't use the query string, so you can't use res.query. POST sends parameters to the request body.
To access POST parameters in the request body that are coming form a form, you can use req.body as described in the Cloud Functions documentation.