The post Adding conversion rate in default GA4 reports appeared first on .
]]>If you haven’t done any customization in the GA4 interface, chances are you will be missing a few important metrics from default reports. One of those metrics is a conversion rate, which is not visible by default the same way as in Universal Analytics (at least at the date of writing).
In this quick guide, I will show you probably the easiest way how to add conversion rate in default GA4 reports.
Open Google Analytics 4 property and pick a report where you would like to see the conversion rate from the left panel. Good candidates to have this metric for example would be “Traffic acquisition”, “Landing page” or “Pages and Screens” reports.
Once you have opened a report, find a pencil icon on the right side above the charts and click on it to edit.
Note: You need to have Editor or Administrator rights for the given GA4 property to be able to do customizations.
Once you are in a “customizer” view, click on “Metrics” from the right panel.
You will see a list of metrics that you can organize the way you want in your report – change order, remove or add new ones. Below all the metrics there will be a field “Add metric” – click on that and search for “Session conversion rate” and “User conversion rate”.
The session conversion rate will show how often sessions with a conversion happen, and the User conversion rate will show the share of Users with a given conversion (across all sessions).
Once those metrics are added, click “Apply”.
Now you will be able to preview your changes before saving a report. You should be able to see the conversion rate metrics that you have added.
The great thing about this is that you can also pick the exact conversion event that you are interested in (from the dropdown) and the conversion rate metric will adjust accordingly.
Once you Save your report additional metrics will be available any time you open it the next time (from default navigation).
In a similar way, you can add conversion rate to multiple default GA4 reports and have more visibility on your channel or page performance. Note that not all default report types will support these metrics or show expected values, so be sure to add it to one of the generic reports first.
Let me know if there will be any questions in the comments below!
The post Adding conversion rate in default GA4 reports appeared first on .
]]>The post Dropdown field tracking in Google Analytics 4 using Google Tag Manager appeared first on .
]]>Since GTM doesn’t track dropdowns (select fields) by default at the moment, we will use a small JavaScript snippet that I prepared earlier. This snippet will listen for any changes in all (or specific) dropdowns on the website and pass relevant information to the Data Layer.
To make it easier we will use a simple code snippet below to capture any changes to dropdown fields and do 2 things:
These values will be fetched by Google Tag Manager and sent to Google Analytics 4, and you can use it to pass information to any other tool.
<script>
(function(){
var dropdowns = document.querySelectorAll('select');
for(var i=0; i <= dropdowns.length - 1; i++) {
dropdowns[i].addEventListener('change', function(e) {
dataLayer.push({
'event': 'dropdownChanged',
'fieldValue': e.target.options[e.target.selectedIndex].text,
'fieldName': e.target.name
});
});
}
})();
</script>
First, we are selecting all elements from the page with <select> tag:
var dropdowns = document.querySelectorAll('select');
Next, we are listening for a “change” event for all matched dropdowns (select fields):
dropdowns[i].addEventListener('change', function(e) {
After that, we send additional information to dataLayer if a dropdown value is changed. In addition to ‘dropdownChanged’ event we are passing the dropdown name and selected value text:
dataLayer.push({
'event': 'dropdownChanged',
'fieldValue': e.target.options[e.target.selectedIndex].text,
'fieldName': e.target.name
});
Note that this template will work out of the box only for default dropdown fields that look similar to this:
And this is how those fields usually look in HTML code:
For dropdown fields that are altered/created using 3rd party plugins this code might not work, since there might be no <select> field at all in the background or it is not updated the same way as a regular dropdown. For those cases, you might need to set up click events or use a custom data layer event to capture required information.
Copy the code above and create a new Tag with the Type “Custom HTML”. If you want to collect dropdown events from all website pages you can use the “All Pages” trigger, but normally you would want to limit this tag only to specific pages where necessary dropdown fields can be found.
To get the dropdown name and value from the data layer we will need to create additional variables in GTM. Go to the Variables section and create 2 new Data Layer variables:
It is important to use exactly the same name as in the JS code snippet since these values are case-sensitive.
To enable dropdown field tracking in Google Analytics 4 add a GA4 event tag that will collect dropdown change events and field values when data layer receives this data.
Create a new tag with the type “GA4 Event”, select your GA4 configuration tag, and enter the event name that you want to see in your reports. I will be using “dropdown_change” in this example.
We want to pass the field name and selected dropdown value to Google Analytics 4 so let’s add two additional event parameters:
As event parameter values we will use corresponding data layer variables that we have just created:
Note that you will need to create custom dimensions “field_name” and “field_value” in Google Analytics 4 interface, otherwise this data won’t be collected. Alternatively, you can use any of your existing custom dimensions as event parameters in the GA4 event tag.
When creating custom dimensions in GA4 (In Admin > Custom definitions section) make sure to use Event scope and exactly the same Event parameter name as in the GTM tag.
Las thing we need to add here is a trigger, so click on “Triggering” and then create a new trigger.
Now select Custom event type and use “dropdownChanged” as the event name, since we have it in our data layer code that we added in a custom HTML tag.
Once you save this it should be attached to your Google Analytics 4 event tag. Save your tag and we are ready to test it.
Enable Preview mode in Google Tag Manager and open a page that contains dropdown (select) fields. You should see a popup in the bottom right corner if the preview has been enabled successfully.
Change values in your dropdown a couple of times and then open the Tag Assistant tab/window to check incoming data layer events.
In the events panel on the left side, you should now see “dropdownChange” for each interaction. If you click on the event name you will see exact data layer values as well. In my example, I have “Radio” as my field value and “g1828-howdidyouhearaboutus” as my field name.
If everything worked as expected you should also see your Google Analytics 4 tag firing when a dropdown value has changed.
Note that dynamic values are passed to the data layer using your HTML structure:
If you would like to use other attributes for your dropdown name and selected value you will need to adjust the custom HTML script accordingly.
To make sure event parameters are reaching Google Analytics as expected you can preview them in GA4 DebugView as well. You should see the same values as in Tag Assistant.
If everything works as expected just publish your Google Tag Manager container and you are good to go!
'fieldValue': e.target.options[e.target.selectedIndex].text,
'fieldName': e.target.name
For example, to get value from input “value” field instead of text and field name from ID instead of “name” attribute, you could change this to the following:
'fieldValue': e.target.value,
'fieldName': e.target.getAttribute("id")
To see how your dropdowns were used and what values were picked you can create a simple report using 2 custom dimensions that we created earlier.
Create a new custom exploration in Google Analytics 4 and import at least 3 dimensions – Event name, Field name, and Field value (same custom dimensions that you have created).
Additionally, add Total Users and any other metrics that you would like to see for selected dropdown values.
Then, under Tab settings scroll down to the Filters section and filter your data by Event name = “dropdown_change” (or event name that you have used).
Now, double-click on dimension and metric names to add them to the report (Field name, Field value, Total Users) and the report should be loaded on the right side of your exploration.
Note that you might see your data in the exploration report only 1-2 days after you first started tracking so it won’t appear here right away.
As you can see is relatively simple to track any standard dropdown interactions in Google Analytics 4 using provided JS template. It might get a bit trickier when your forms are using non-standard dropdowns as implementation will vary depending on its structure. We might cover the most common approaches for other dropdown types in separate blog posts in the future.
Good luck and let me know in the comments if you have any questions!
The post Dropdown field tracking in Google Analytics 4 using Google Tag Manager appeared first on .
]]>The post <strong>Set up Google Ads to BigQuery export</strong> appeared first on .
]]>Before we continue make sure you have:
You can find how to create one using Google’s help center.
Alternatively, you can check Step 2 from this article with examples of how to set up a Google Cloud account. Usually, BigQuery API and BigQuery Data Transfer Service are enabled by default.
To connect data you will need to have access to a Google Account which you want to import data from.
In case Google Ads access is on another email (not on account associated with Google Cloud) you will need to add it with appropriate permissions.
If Account is owned by you, you can just add BigQuery Admin permissions, or very specific roles required to set up data transfer:
bigquery.transfers.update
permissions to create the transferbigquery.datasets.get
and bigquery.datasets.update
You can check this documentation if you want to use a more advanced approach for permission management.
Open your Google Cloud project and from the menu go to BigQuery > Data Transfers.
Click on “Create new Transfer” and from the source select “Google Ads”.
Provide descriptive data transfer name and select transfer schedule. Depending on how often you want this data to be loaded from Google Ads to BigQuery you can change this here.
If you want to export this daily you can select “Daily” and provide a time when it should run every day.
Then you need to provide a destination for data export. There will be multiple tables created by this export so it’s best to use a separate dataset.
Click on the Data set field and Create a new data set.
Provide details for new data set in the prompt shown by google and it should now appear in the input field.
Next, you need to provide your Google Ads account ID.
You can usually see that ID on the top right corner. Copy that value and paste it into this field.
Click “Save” on the Transfer setup page and you will be asked to authorize to provided Ads ID.
You can authorize access from your existing account or use another one (just make sure that Google account is added with sufficient accesses – more on that below).
If everything goes well then the transfer should be successfully created and you should see details page:
There will be no data yet, and it will be loaded next time according to the schedule that you have just specified. Next, will take a look at how to get historical data from Google Ads to BigQuery.
If you haven’t added billing details to Google Cloud, you might see a following error message after trying to save data transfer.
To fix that just visit the “Billing” section and make sure you have an active payment method added and a Billing account created. It doesn’t mean that you will be charged right away for your data export, in most cases, it will be enough with the free tier limits that BigQuery provides. But in case you do more complex queries or load a lot of data you might start seeing some costs in your bill.
Another error message that might be shown could be related to insufficient permissions. Make sure that email that has access to Google Ads has access to BigQuery as well. This was mentioned in the Point 3 in the prerequisites.
You need to have a BigQuery Admin role for that email or more specific roles mentioned in Google Cloud documentation.
From your Transfer details page (that opened automatically after the transfer was created) find the “Schedule backfill” link in the top right corner.
Then select “Run for a date range”, select time interval that you are interested in, and click OK.
Once you refresh the project details page you should see all pending queries for each date and their current status. You can re-run any queries that failed for some reason and have an overview of what data is available. After backfill is scheduled it might take some time (multiple hours) before all requested data is loaded into BigQuery.
Once data for at least 1 day was exported, all tables will be available under your dataset name as usual.
As a next step, you can explore how you can query partitioned tables from this export and some sample queries provided by Google.
The post <strong>Set up Google Ads to BigQuery export</strong> appeared first on .
]]>The post Input field error tracking in Google Analytics 4 and Google Tag Manager appeared first on .
]]>In this post, we will take a look at how to set up input field error tracking in Google Analytics 4 and GTM, and how to view collected data afterward.
We will tackle a specific tracking problem of input fields that are using a default HTML client-side validation method.
By default, if a field doesn’t meet the requirements, the error text is shown as a small popup, without adding any DOM element that could potentially be used with a visibility trigger. This creates a small problem since there is no default trigger in Google Tag Manager that can activate a tag on these events.
To add necessary tracking we will be utilizing Constraint Validation API and dataLayer events that I will show you in the examples below.
We will be using a code template to capture client-side input field validation errors, so you can copy that and add it to your custom HTML tag. It should work in the majority of cases, and I will explain what this code does in a second.
<script>
(function(){
var inputs = document.querySelectorAll("input");
for(var i=0; i <= inputs.length - 1; i++) {
if(inputs[i].validationMessage !== "") {
window.dataLayer.push({
"event": "fieldError",
"fieldName": inputs[i].getAttribute("name"),
"errorMessage": inputs[i].validationMessage
});
}
}
})();
</script>
Next, you need to add a trigger when a user tries to submit the form. Usually, these errors are shown when you click on a submit button, so we can use that element.
Your final trigger configuration will look similar to this:
Once you save the trigger, and your tag, a dataLayer event “fieldError” will be sent for each validation error shown to the user.
Let’s take a quick look at what the code does line by line before we finalize Google Analytics event setup.
First, we extract all <input> elements from the page:
var inputs = document.querySelectorAll("input");
Then, for each input field, we are checking if there are any validation errors by using .validationMessage using Constraint Validation API.
for(var i=0; i <= inputs.length - 1; i++) {
if(inputs[i].validationMessage !== "") {
If the validation message isn’t empty it means this field had an error. In this case, we send a dataLayer event “fieldError”. It contains 2 additional parameters:
window.dataLayer.push({
"event": "fieldError",
"fieldName": inputs[i].getAttribute("name"),
"errorMessage": inputs[i].validationMessage
});
Once we have the code template in place we will have dataLayer available, but it still won’t reach Google Analytics until we create a tag for that.
Create a new tag with the type “Google Analytics: GA4 Event”, select the GA4 configuration tag, and provide the event name that you want to see in your reports. In my case, I will use “signup_field_error”.
To collect field name and exact error message text we need to add event parameters using dataLayer that we have just added in a custom HTML tag.
Under the event parameters section add 2 parameters:
Of course, you can use different names here, just be sure to align it with custom dimensions names in Google Analytics 4.
As field values we will use dataLayer contents, so click on the plus sign near the value input field and create a new variable by clicking on a “+” icon once again.
Save the variable and do the same for the error message. The data Layer variable name will be “errorMessage”.
Your final event should look similar to this:
Now we only need to add a trigger that will be a custom event from the same data layer, named “fieldError”.
Each time fieldError event will reach the data layer we will send a GA4 event with dynamic information about the field name and error text. Save your tag, and now we only need to register event parameters in Google Analytics before we can test it.
Before we proceed, we have to create additional custom dimensions for additional event parameters or parameter values won’t be stored in Google Analytics 4.
Open Admin section in your Google Analytics account and under the GA4 property select “Custom definitions”. Then create a new custom dimension.
Then create 2 event-scoped dimensions using exactly the same event parameter values from our GTM tag:
Once you are ready you should see them in the custom dimension list. Now, we are ready to test the error tracking implementation in GTM.
To test implementation enable GTM preview & debug mode and then try to submit an empty form or provide incorrectly formatted data to trigger a default error message.
For each field error (even if it’s not directly visible on the page) you should see a “fieldError” event in the tag assistant window. By clicking on the event and expanding dataLayer contents you should see the correct field name and error text. The same should be visible in your GA4 event tag when you click on it:
You can also double-check the setup in GA4 DebugView to make sure events are passing through the correct information. If all events have expected field and error message values – Publish your changes from GTM and start collecting error messages.
Common issues and possible solutions:
To see what error messages users experience on your form and what are the most problematic fields you can create a simple Exploration report inside GA4.
From metrics select Total Users. If you would like to see something else, just add them to the list in the same way.
Next, in the Tab Settings scroll down to the Filters section and select “Event name” as our filter. We will include only sign_up_field_error event.
Now, we only need to double-click on all necessary metrics and dimensions to display them in a report.
Based on this data we could quickly see that for some reason biggest issues are with filling out First name, Last name and Password. We can also group it in a separate tab to display aggregated data only for field names:
As you can see, using Constraint validation API and provided template it’s relatively easy to collect insights about errors that customers are experiencing while filling out your form. You can easily adjust it if needed to fit your specific implementation (e.g. if you would like to group error messages or include additional field parameters).
Note that this code covers only default client-side validation errors. If your forms are using other ways of displaying a validation error you might need to use another approach such as custom dataLayer implementation on the website, visibility trigger, or custom DOM scraper to get this data.
I hope you found this useful, and as always, let me know in the comments if you have any questions!
The post Input field error tracking in Google Analytics 4 and Google Tag Manager appeared first on .
]]>The post Mouse Hover tracking in Google Tag Manager and Google Analytics 4 appeared first on .
]]>Since mouse hover is not available in Google Tag Manager as a default trigger we will need to use JavaScript to trigger a dataLayer event. I’ve prepared a simple code template that we will use in a custom HTML tag.
<script>
(function(){
var cssSelector = "section.main-about";
var dlEventName = 'elementHover';
var targetElement = document.querySelector(cssSelector);
if(targetElement) {
var eventTimout;
var eventTimout2;
var eventTimout3;
targetElement.addEventListener('mouseenter', function(){
eventTimout = setTimeout(function(){ sendEvent(5, dlEventName); }, 5000);
eventTimout2 = setTimeout(function(){ sendEvent(10, dlEventName); }, 10000);
eventTimout3 = setTimeout(function(){ sendEvent(30, dlEventName); }, 30000);
});
targetElement.addEventListener('mouseleave', function(){
clearTimeout(eventTimout);
clearTimeout(eventTimout2);
clearTimeout(eventTimout3);
});
}
function sendEvent(duration, event) {
window.dataLayer.push({
'event': event,
'hoverDuration': duration
});
}
})();
</script>
Let’s take a quick look at what this code does by splitting it into parts.
At the very top, we use CSS selectors to define what element we want to add hover tracking for.
var cssSelector = "section.main-about";
In the first example, we will take a look at how to add tracking to a single website element. In the extended example, we will fetch multiple elements at the same time.
If you don’t know what CSS selectors are and how to work with them in GTM, check this guide.
On the top, you also have the option to adjust the data layer event name. You can either leave it as it is or use your own name. This will be used for a trigger that will activate the GA4 event tag.
var dlEventName = 'elementHover';
In my example, “elementHover” is the data layer event name that will be available in GTM once elements are hovered. You can read more on how dataLayer works in GTM if you haven’t worked with that before.
In the next block, if our target element exists, we are listening for “mousenter” and “mouseleave” events.
If a visitor hovers a mouse over an element for consecutive 5 seconds – the first hover event is sent to dataLayer.
When the visitor hovers for 10 seconds or 30 seconds – additional events are sent to dataLayer.
targetElement.addEventListener('mouseenter', function(){
eventTimout = setTimeout(function(){ sendEvent(5, dlEventName); }, 5000);
eventTimout2 = setTimeout(function(){ sendEvent(10, dlEventName); }, 10000);
eventTimout3 = setTimeout(function(){ sendEvent(30, dlEventName); }, 30000);
});
targetElement.addEventListener('mouseleave', function(){
clearTimeout(eventTimout);
clearTimeout(eventTimout2);
clearTimeout(eventTimout3);
});
}
You can adjust the time of thresholds by editing duration in milliseconds. For E.g. 5000 in the example below stands for 5 seconds hover time.
eventTimout = setTimeout(function(){ sendEvent(5, dlEventName); }, 5000);
To trigger an event after 2 seconds of mouse hovering just change it to 2000 like this:
eventTimout = setTimeout(function(){ sendEvent(2, dlEventName); }, 2000);
If you will be using multiple thresholds for the same element, you need to edit the first parameter of the sendEvent() method so that correct values are available in dataLayer.
So this value:
sendEvent(5, dlEventName);
Will become:
sendEvent(2, dlEventName);
The code below ensures that no events are triggered if a user moved their mouse away from the element before a specified number of milliseconds has passed.
targetElement.addEventListener('mouseleave', function(){
clearTimeout(eventTimout);
clearTimeout(eventTimout2);
clearTimeout(eventTimout3);
});
If you just want to add hover tracking for one threshold in GA4, leave only 1 “eventTimeout” variable.
The full code example will look like this:
<script>
(function(){
var cssSelector = "section.main-about";
var dlEventName = 'elementHover';
var targetElement = document.querySelector(cssSelector);
if(targetElement) {
var eventTimout;
targetElement.addEventListener('mouseenter', function(){
eventTimout = setTimeout(function(){ sendEvent(5, dlEventName); }, 5000);
});
targetElement.addEventListener('mouseleave', function(){
clearTimeout(eventTimout);
});
}
function sendEvent(duration, event) {
window.dataLayer.push({
'event': event,
'hoverDuration': duration
});
}
})();
</script>
At the very bottom, we have a method that sends a data layer event and we reuse that for any specified thresholds. In addition to the event name, we are also passing the “hoverDuration” attribute that can be used as a data layer variable in your tags.
function sendEvent(duration, event) {
window.dataLayer.push({
'event': event,
'hoverDuration': duration
});
}
Once you have familiarized yourself with the template, let’s adjust it and create additional components for our tracking to work.
First of all copy the JS template that was provided above, and in GTM create a new Custom HTML tag:
The main thing that you need to adjust in any scenario is the CSS selector variable value.
var cssSelector = "section.main-about";
Instead of “section.main-about” you should use your own value depending on which element you want to add hover tracking for.
On my website I will track sidebar categories:
So to get the CSS selector I will inspect the element (Right click > Inspect Element). And I can see that I can track whole block hover events using element ID – “categories-2”.
Because this is an ID attribute my CSS selector will be “#categories-2” and I will change the variable value as well:
var cssSelector = "#categories-2";
If you didn’t understand what just happened, I highly recommend reading an introduction to CSS selectors that you can find in my blog. I’m using # before the ID name as part of the CSS selector syntax and it will be used by a script to point to the correct element.
Now, for the sake of example, I will also adjust thresholds when the first hover event fires and change it from 5 seconds to 3 seconds. So I need to change 2 values – one that is sent to dataLayer and a second that is used for the timer.
Changing this:
eventTimout = <span class="hljs-built_in">setTimeout</span>(<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){ <span class="hljs-title function_">sendEvent</span>(<span class="hljs-number">5</span>, dlEventName); }, <span class="hljs-number">5000</span>);
To this:
eventTimout = setTimeout(function(){ sendEvent(3, dlEventName); }, 3000);
Now, we need to activate the hover tracking script by adding a trigger. Click on “Triggering” and create a new trigger.
We need this tag to be active once the HTML structure has loaded, so from the trigger type select “DOM ready”.
Since my element can be accessed from any page I can heave the default settings and activate it on all pages. If you want to limit it to a specific page just pick “Some DOM Ready Events” and provide additional conditions.
NB! In some cases, your element might not be available when the page fully loads, but only after certain clicks or actions. These scenarios will require you to use visibility or custom dataLayer events to trigger the main element hover tracking script. Make sure to test your implementation properly to make sure everything is running smoothly.
Save the trigger and then save the Custom HTML tag.
Next, we need to create a GA4 event tag that will capture our hover data layer event. From the Tags section create a new tag with the type “GA4 Event”.
If you are tracking multiple hover duration thresholds you will need to pass this information as an event parameter in GTM.
We will use the dataLayer value that was passed in the ‘hoverDuration’ attribute from our Custom HTML tag.
Now it should appear as a dynamic value in the GA4 event tag:
Next, we need to add hover_duration custom dimension in GA4, otherwise, it won’t appear in the reports.
Use the same event parameter name as in GTM configuration – “hover_duration”, and provide descriptive details about this custom dimension. I’m using custom dimensions since I’m interested only in the thresholds for the hover events. If you like, you can also adjust it to work with custom metrics and make additional calculations that are possible only for metrics (e.g. calculate avg. hover duration for specified elements).
Once you save it, go back to GTM and add the last piece of the setup – a trigger.
This tag now will trigger each time when hover event occurs and triggers “elementHover” data layer event.
When you have added all the setup in Google Tag Manager and GA4 it’s time to test it. Enable Preview mode in GTM and hover tracked element for at least provided duration threshold.
If events worked as expected you should see a separate dataLayer event for each threshold. In my example, there are 3 of them – for 3 seconds, 10 seconds, and 30 seconds.
If you click on any of the dataLayer events from the left sidebar, you should see the hover duration value and confirmation that the GA4 Event tag has fired.
You can also double-check your events in GA4 DebugView by opening Google Analytics 4 property and going to Configure > DebugView. You should see your events in the event timeline and a hover_duration passed as a parameter.
If your setup doesn’t work as expected you might have some issues with the edited code template or tag configuration.
If you don’t see any of the events after hovering tracked element check these 2 things:
If you see a data layer event in preview mode but the GA4 tag is not fired:
After you collect some data you can create a custom Exploration report to view hover count and duration statistics.
Create a new exploration report and include the following dimensions: Event name, Element hover duration (name that you have used for hover_duration dimension).
Include Total users as a metric or Total events if you prefer that better.
Double-click on all dimensions and metrics from the Variables tab to include them in the report.
Add your event name as a filter and click Apply.
You will then see a report on the right side with the element hover user (or event) count split per hover duration. You will need to wait a day or two after hover tracking implementation before any data will appear in this report.
There might be cases when you want to track hover for multiple similar elements on the page and maybe check which of those are hovered more often than others. If this is your use case, below is a template that you can use for a Custom HTML tag instead:
<script>
(function(){
var cssSelector = "a.post-thumbnail img";
var dlEventName = 'elementHover';
var elemNameAttribute = "alt"; // change this to the attribute name to differentiate elements.
// E.g. use "src" to use image source URL
var targetElements = document.querySelectorAll(cssSelector);
if(targetElements.length > 0) {
for(var i=0; i <= targetElements.length - 1; i++ ) {
addEventsToElement(targetElements[i]);
}
}
function addEventsToElement(targetElement) {
var eventTimout;
var eventTimout2;
targetElement.addEventListener('mouseenter', function(e){
var elemName = targetElement.getAttribute(elemNameAttribute);
eventTimout = setTimeout(function(){ sendEvent(2, dlEventName, elemName); }, 2000);
eventTimout2 = setTimeout(function(){ sendEvent(5, dlEventName, elemName); }, 5000);
});
targetElement.addEventListener('mouseleave', function(){
clearTimeout(eventTimout);
clearTimeout(eventTimout2);
});
}
function sendEvent(duration, event, elemName) {
window.dataLayer.push({
'event': event,
'hoverDuration': duration,
'elementName': elemName
});
}
})();
</script>
The key changes here are that we are using a CSS selector to target all matching elements and the hover tracking event will include an additional element name parameter.
At the very top you have the ability to adjust the parameter name that will be used as an element unique identifier for reports:
var elemNameAttribute = "alt";
In this example, it will fetch the “alt” attribute of a hovered element. You can easily change that to “src” to fetch the image URL or any other parameter. Note that GA4 custom dimensions allow collecting only up to 100 characters, so in case the URL exceeds this limitation it will be trimmed.
You also have an additional parameter in dataLayer called “elementName” that can be passed to GA4 as a custom event parameter (custom dimension) in a similar way that we did with “hoverDuration”.
function sendEvent(duration, event, elemName) {
window.dataLayer.push({
'event': event,
'hoverDuration': duration,
'elementName': elemName
});
}
Since there is no default hover trigger in GTM yet we have to use custom JS to get hover tracking in place. If you haven’t worked before with CSS selectors or JavaScript it might be a bit overwhelming to make this setup, so hopefully provided examples and explanations will be useful.
Let me know in the comments if you have any questions!
The post Mouse Hover tracking in Google Tag Manager and Google Analytics 4 appeared first on .
]]>The post Google Tag Manager export (and import) any container appeared first on .
]]>Open the “Admin” section in GTM and select the “Export Container” option under the container menu.
Then you can pick the workspace or container version where you want to export your setup. If you want to export something that is not published yet you should pick one of the workspaces.
Once you select a version or workspace you will see a summary of all your container components.
By default everything will be pre-selected and if you click “Export” it will download a JSON file with all GTM container contents.
Usually you won’t need a full export unless you are migrating whole setup to another GTM container. To export only some of the tags you can unselect everything and then use a search box to find exact components that you want to export.
If you select components that rely on other variables / tags / triggers which are not included in the export then you will see a warning message.
It’s best to make a partial export including all linked references otherwise the setup won’t work when imported to another container. GTM will show a warning sign next to selected elements that are missing some references.
If you hover on it you can easily add any missing components by clicking “Add” button.
In some cases you might want to skip several references and proceed with the export inspite of the warning for referenced components that already exist in the target container (where you will make an import).
Once you are ready click on “Export” and you will download JSON file with your GTM configuration. You can also open it in any text editor and make some changes in bulk (e.g. changing conversion IDs, adjusting naming convention, etc.)
To import a container go to Admin section and now pick “Import Container” option.
For “Merge” option you can select if you want to overwrite conflicting components or rename them. I always pick “Rename” just in case I have some components with the same name. You can delete them from the workspace after reviewing imported components.
After you have provided all the details you can preview changes, and if everything looks good – Confirm.
Now you can edit new tags, triggers and variables as you would normally do in a workspace. Any components that have conflicting names with existing tags will be added a “import_1” to the name (in case you picked Rename option).
As you can see it is now very easy to export and import Google Tag Manager contents between different containers. The common use cases that you might want to use it for:
The post Google Tag Manager export (and import) any container appeared first on .
]]>The post GTM Page view, DOM ready, and Window loaded – Explained appeared first on .
]]>By default Page View trigger types are ordered by how early they are fired. Consent Initialization will be triggered first and Window Loaded will be activated last.
This trigger type is specifically designed to be used for setting and updating Google consent settings. It will be the first one to fire once the page is loaded.
The only use case for it would be to trigger Consent Management Platform tags or custom tags that set user consent. You shouldn’t use this trigger on any other tags.
There is a default trigger “Consent Initialization – All Pages” that can be used for most consent-related needs, but if you need to limit certain consent tags to a specific domain or page, you can easily create a trigger with a custom condition.
Initialization triggers will be the second in line to fire tags. Unline Consent Initialization you can use it to fire other non-consent-related tags that you want to execute on the page as early as possible.
There is a default Initialization trigger that can be used to trigger a tag on any page when “Initialization” is fired.
There are two set-up scenarios I see it being useful:
The Page View trigger in GTM is the next one on the priority list and will be fired when the browser starts to load the page. It is very commonly used for any main tracking tags like – GA4 configuration, Universal Analytics page view tag, Hotjar base tag, Google Ads remarketing tag, etc.
There is a default trigger “All Pages” already available in GTM that can be used for tags that should be fired on any page as soon as it starts to load.
DOM Ready is fired as soon as the page HTML structure is finished loading. The trigger name “DOM” stands for Document Object Model.
Use this trigger type only for the tags that require some data from your HTML structure. For example, if you would like to extract a product title or other page meta-data and pass in an event, you would need to use at least DOM Ready trigger (or lower priority).
Also if your tag is using any variables that require HTML content to be loaded (E.g. DOM Element variable), you would need to use DOM Ready trigger type.
Any variables that extract data from the page won’t have expected data available when using triggers with higher priority (E.g. Page View).
Window Loaded event in GTM is the trigger with the least priority and is fired when all page resources have been loaded. It will be fired when all images, scripts, and other attachments have been loaded in the browser.
Some use cases when you might want to consider using this trigger type:
The most critical tags should be fired as early as possible (Initialization or Page View) while other non-essential ones can be delayed to Window Loaded or DOM ready to allow main site content to load a bit faster. With the lower priority triggers, there is a chance that some small portion of your visitors won’t ever load the tags (e.g. if they leave the page before the site fully loads).
I hope this short guide gave you more understanding about when you could use all of the Page View trigger types in Google Tag Manager. Let me know in the comments if you have any questions!
The post GTM Page view, DOM ready, and Window loaded – Explained appeared first on .
]]>The post DebugView in Google Analytics 4 (GA4) – Introduction appeared first on .
]]>In this post, we will take a look at how to enable DebugView in GA4, how to use it, and how to interpret displayed information.
Open Google Analytics 4 property and from the left menu go to Configure > DebugView.
You won’t see any data here yet until any browser loads GA4 with enabled debug mode.
There are multiple ways how to display real-time data in this DebugView:
gtag('config', 'G-12345', {'debug_mode':true });
The most convenient way how to make events flow into DebugView is to use GTM Preview mode. When Preview mode is loaded head back to the GA4 report and you should start seeing your interactions here.
If you don’t start seeing at least the “page_view” event here try to reload the DebugView tab in the browser (it usually helps me and events are loaded right away).
NB! Any collected data with a debug_mode enabled won’t be available in regular Google Analytics reports. Avoid publishing tags where this attribute is enabled for all visitors.
On the left side of DebugView you will always see event timeline split per minute un to the last available minute. Number of events that appeared in the current minute will be shown in the big circle above the timeline. Events that happened several minutes ago will appear in a smaller circle showing event count in given minute.
In this example we can see that 6 events have happened in the current minute and there was 1 event that occured on 10:55 AM. You can use this timeline as a navigation in Google Analytics DebugView to inspect collected data for selected time frame.
It is also possible to use multiple devices/browsers for debugging. For example you could enable preview mode from different machines and then switch between those devices under device list above event timeline.
By default on the right side from event timeline you will see a more granular view of your events. DebugView will show live feed of all collected data in a chronologically ordered timeline.
You can click on each event to see more details about what attributes are being passed to Google Analytics. This is particularly useful to verify collected values if you are passing additional dimensions to GA4 (default or custom).
You can then click on each parameter or user property to see what value was received.
When a user property was set you will also see a special label in the event feed.
You can use this to identify if your user properties are being updated when expected more easily.
If your event was marked as a conversion in GA4 interace, then DebugView will use a different color to highlight it. This allows to notice valuable events more easier.
To focus only on a subset of events you can pause event feed by clicking on the top of the block (see screenshot). If will freeze the timeline and no new events will appear in the DebugView until you click again and unpause it.
On the right side you can find a summary of all events collected in the last 30 minutes for selected Debug Device. Separately Google Analytics will also try to group conversion (green) and error (orange) event count on top.
I tried to send an exception event that should be registered in the orange section, but it seems it’s not working as I expected (at least for web). Most likely will work for app related exceptions and app crashes. Let me know if this worked for you on the web!
If you click on any event from the Top events section a detailed list of parameters will appear similarly as in the event feed. When you click on a parameter name you will see a full histrory of the values for that parameter. This section will be great for a higher level overview of how certain event parameters or user properties changed over time for the same event.
Under top events you will see a summary of all active user properties (user scoped custom dimensions).
If you click on the clock icon GA will show you how this user property changed over time and when that happened (Last 30 minutes).
In the previous version of GA not all of the data was available in the realtime reports and you had to either wait some time before it become available or trust that all data passed in the request will reach it’s destination.
With the new DebugView Google Analytics 4 has significantly improved ability and speed of debugging events before publishing Live. Also more granular view on default and custom dimensions (parameters) gives more visibility and understanding of your tracking setup behind the scenes.
The post DebugView in Google Analytics 4 (GA4) – Introduction appeared first on .
]]>The post Only 2 months of data in GA4 reports – How to fix it appeared first on .
]]>This makes custom reports in GA4 quite unusable if you want to compare certain event performance month over month, for example. The good thing is that it can be easily changed, the bad thing – you’ll have to wait to collect new data before you can access it.
When you initially create a Google Analytics 4 property it will set data retention to 2 months. Google stores user and event-level data for the given period. When data “expires” it is deleted from GA4 servers and thus is not available for you in custom reports.
Note that standard aggregated reports are not affected by this expiration period.
To have more flexibility in your custom reports you can change the expiration period by going to Admin > Property > Data Settings > Data Retention section.
From there change the Data retention period from 2 months to 14 months. Longer periods of data retention (up to 50 months) are available only to GA4 360 customers.
When you save this setting, after 24 hours it will take effect. All fresh data will be using 14 month expiration period and will be available in custom reports for a little bit more than a year.
Note that some data in GA4 will be disregarding the data retention period in these settings (e.g. age, gender, interests), you can read more in official documentation.
No. Unfortunately, the change will affect only new incoming data. You will still need to wait for a couple of months before you can select a period longer than 60 days in custom exploration reports.
Each new day Exploration reports will “unlock” additional days in the past over 60 days, up until 14 month period (or more if you are GA4 360 customer).
No. BigQuery exports data daily, and it is stored in your Google Cloud project, so you will always have a full and more precise event log stored there regardless of GA4 data retention settings.
If you are struggling to get some historical information from GA4 you could this get data from BigQuery (if you were exporting GA4 events to BigQuery for a given time period).
As you can see default data retention setting can create a lot of pain when using GA4 exploration reports. When creating a new GA4 property double-check if this is set to at least 14 months if you want to have that data be available later.
For a little bit more sophisticated data analysis GA4 can no longer be used in the same way as Universal Analytics, so you will have to explore BigQuery.
The post Only 2 months of data in GA4 reports – How to fix it appeared first on .
]]>The post CSS selectors in Google Tag Manager – a practical guide appeared first on .
]]>If you haven’t worked a lot with CSS selectors, this short guide will hopefully give you more clarity. We will also go through some practical examples of the most common use cases.
CSS selectors are a set of rules (or patterns) to select elements on the website. In programming CSS selectors are used for applying styles for HTML elements.
Think of CSS selector as an address. To find an object that you are searching for you need to have a correct address. If address is wrong you might find nothing or it might lead you somewhere you didn’t want to be in the first place. CSS selectors in programming (and in Google Tag Manager) is just a set of rules how to correctly define address of an element on your page – a button, form, navigation link, etc.
For example, when you create a website layout in HTML you need to write CSS rules about how those elements will be positioned on the page, what color they will be in, the dimensions of an element, etc.
A simple example of a CSS rule:
a.navigation {
color: black;
font-size: 20px;
}
In the example above a.navigation is a CSS selector and values contained in the curly brackets are formatting rules.
If you want to target any element from the website either for interaction tracking or to extract any dynamic data – most likely you will need to use CSS selectors to do it more efficiently.
Usually, you have the option to provide a CSS selector in your targeting settings in a tag, variable, or trigger.
For triggers you can usually select “Click Element” as your variable and “Matches CSS selector” as the condition:
In tags and variables you have an option to provide either ID attribute or CSS selector from the dropdown.
Let’s take a look at the most common places in GTM where CSS selectors will be most useful.
The most common trigger types where CSS selectors are used are the Click triggers.
You can target any element on the website and fire an event when a visitor clicks on it.
For e.g. if you want to trigger an event every time somebody clicks on a link with the class name “navigation” you could use this set of rules.
I’ve seen many GTM implementations where a Click text or other workarounds are used where a simple CSS selector would suffice. Learning some element targeting basics would be most beneficial for setting up any click-based triggers.
Another trigger type where a CSS selector will be required is Element visibility. You have an alternative option to trigger an event based on the ID attribute, but most often it is not available when needed.
To target element visibility based on the CSS selector, you need to pick the selection method as shown below and provide a selector query.
I have a separate blog post about Element visibility triggers you can check that out.
Using CSS selectors you can also target a form where you want to track submissions.
Usually, it will be a “Form Element” with a “matches CSS selector” rule.
Using DOM Element you can get any element from the website by providing an ID or CSS selector.
There is a separate post dedicated to the DOM Element variable. You can read it if you want to learn more.
You can use a CSS selector to get element visibility status or percentage using this variable type.
When you need to extract some information that couldn’t be accessed by the DOM Element variable you might need to use CSS selectors in the Custom JavaScript variable as well.
From the default tag types, CSS selectors could be used in custom HTML tags querying website elements. You could either extract necessary information or trigger event based on non-standard actions like mouse wheel scroll, copy/paste events, etc.
There are some CSS patterns and methods that are used more often than others. In my subjective list below I ordered them by “popularity”, starting with the most common. We will go through each example one by one.
Before we start looking at examples you need to know how to view website HTML source code and inspect elements that we are interested in. If you already know how to do that, just skip to the next section.
The easiest method so far is by using the browser’s built-in “Inspect mode”. To Inspect any element just right-click on it and select “Inspect” from the menu.
This will open a developer console showing the HTML code of your page and highlighting inspected elements.
You can use it to easily find elements in HTML, check what attributes you can find attached (for CSS selectors), or search for parent or child elements.
Parent elements will be any elements indented more to the left. In the example above a parent element for the link would be H2 with the class name “entry-title”.
Sometimes HTML structure and attribute values may be different on mobile devices versus desktops. When inspecting your elements it is helpful to preview the website on different screen sizes to make sure your CSS selectors are working for those scenarios as well.
You can easily switch between different device screen sizes using this button in the developer console:
This screenshot is from Chrome, but you will see a similar option in other major browsers too.
Class name selector example:
.article-content
The most common way how you can target an element on the website is by using a class name.
A class name value is stored in the HTML element “class” attribute (see screenshot above). Often elements may have multiple class names which are divided by a space.
In the example above we have a link (anchor HTML element) with 2 class names – “skip-link”, and “screen-reader-text”.
By adding a dot before any class name you will create a CSS selector that points to any element with a given class name.
The syntax for using any class name as a CSS selector:
.<class-name>
The link from the example above could be targeted using any of the following two CSS selectors:
.skip-link
.screen-reader-text
We can also combine all class names provided for the same element to make the targeting rule more accurate (without spaces):
.skip-link.screen-reader-text
This is how this rule would look in GTM click trigger:
NB! If your CSS selector matches multiple elements on the page then it might lead to unexpected results. Avoid using a single class name in CSS selector unless you are certain it’s unique per page or website. Class names can usually be combined or used together with parent selectors to ensure correct targeting.
Usually, most HTML elements have a class name, so even if it’s not unique for a selected element, you can combine multiple of them to target what you need (as shown above).
Since same class names can be used multiple times on different element we might need to provide more information about where targeted element is located in the DOM. In the context of Google Tag Manager in most of the use case you will need a CSS selector that targets only 1 element. For example – specific CTA button click tracking, when certain banner is shown on the page, on specified form submit, and so on.
Let’s take a look at the example:
<div class="product-card">
<div class="add-to-basket-cta">Add to basket</div>
</div>
<div class="related-products">
<div class="related-product">
<div class="add-to-basket-cta">Add to basket</div>
</div>
</div>
We want to add Click event to “Add to basket” button from a product description page, and we can see that button has a class name of “add-to-basket-cta”.
If we use just the class name selector we would also trigger an event when Related product “Add to basket” button is clicked (which we don’t want):
.add-to-basket-cta
So, to target only button which is located inside “.product-card” element we can add it before button class name selector and divide by space like shown below:
.product-card .add-to-basket-cta
You can use this method when multiple elements contain the same class name but have different “parents”. It would also work if your target element is not direct child of a parent. For example:
<div class="product-card">
<div class="product-description">
<div class="add-to-basket-cta">Add to basket</div>
</div>
</div>
Learning only these 2 concepts – class name selectors + descendant selectors would already give you a huge variety of elements that you can target using Google Tag Manager.
If you want to target only a direct child of any element you can do that by adding a “>” symbol between 2 classnames (or other selector types).
Example with multiple Add to basket buttons under same parent element:
<div class="product-card">
<div class="product-description">
<div class="add-to-basket-cta">Add to basket 1</div>
</div>
<div class="add-to-basket-cta">Add to basket 2</div>
</div>
To select only “Add to basket 2” button, you could use following CSS selector (direct child):
.product-card > .add-to-basket-cta
Same as with class names we can search for an “id” attribute of an element and create a CSS selector by adding # before the name. For example if we have following HTML element:
We can target it by using this CSS selector:
#main-article
ID attribute is most likely to be unique on the page, so you might not need to use other parent/child combinations showed above. In Google Tag Manager you often have an option to provide an ID value instead of CSS selector, so this might not be used very often.
Sometimes different element types are using same attribute values (e.g. class name). Element type is essentialy a HTML tag name and we can use it in CSS selectors without any additional prefixes.
For example if we have a list of these elements:
<div class="text"></div>
<h2 class="text"></h2>
<p class="text"></p>
we can select each one of those using following CSS selectors:
div.text
h2.text
p.text
We are just using HTML tag name and adding a class name. We can also use them without any other attributes to select all elements with that tag name on the page.
div
h2
p
Sometimes elements don’t have a distinct class name or ID. In these cases we can use any other atttributes attached to HTML element.
For example, we have following links on the website:
<a href="https://www.facebook.com/testPage/">Link 1</a>
<a href="https://www.instagram.com/testPage/">Link 2</a>
<a href="https://www.twitter.com/testPage/">Link 3</a>
To select only Instagram link I could use following CSS selector:
a[href="https://www.instagram.com/testPage/"]
Another example:
<a href="#" data-value="link-1">Link 1</a>
<a href="#" data-value="link-2">Link 2</a>
<a href="#" data-value="link-3">Link 3</a>
To select only Link 3 we could use following selector:
a[data-value="link-3"]
The general syntax for selecting any attribute that exactly matches provided value is this:
[attribute="value"]
So it is possible to use these selector types without any tag name or class name provided as well:
[data-value="link-3"]
Sometimes it is useful to select all elements that contains a particular class name or attribute value. For this we can use a variation of atttribute selectors by adding star “*” after attribute name.
Example selector:
a[data-value*="link"]
This selector would target the first 3 links below:
<a href="#" data-value="link-1">Link 1</a>
<a href="#" data-value="link-2">Link 2</a>
<a href="#" data-value="link-3">Link 3</a>
<a href="#" data-value="other">Link 4</a>
There are multiple other options for partial matching in CSS selectors. You can use “starts with”, “ends with” and other matching types.
Note that you can use this also for class names in the same way as for attributes.
a[class*="link"]
Selector above would target all links where any of the classnames contain value of “link”. So Link 1 and 2 in this example.
<a href="#" class="link-1">Link 1</a>
<a href="#" class="glowing-link sale">Link 2</a>
<a href="#" class="glowing">Link 3</a>
<a href="#" data-value="link-4">Link 4</a>
Sometimes you might need to trigger same event when multiple different elements are clicked. One way is to create multiple different triggers with different CSS selectors, but you can also combine them into one by using a comma.
Let’s say we want to trigger an event when any of these elements are clicked:
<a href="#" class="link-1">Link 1</a>
<div class="main-banner"></div>
<div class="main-banner-2"></div>
<h2>Some title</h2>
<div class="cta-button">Sign up</div>
We know how to select them separately or some of them, so we can combine that into a single CSS selector like this:
.link-1, [class*="main-banner"], h2, .cta-button
And this is how it could look like in your GTM trigger.
We have covered the main components and syntax examples for CSS selectors (in my subjective view) and how those can be used in Google Tag Manager. There are more selector types out there which are used less frequently and you can learn more about them on MDN website.
As I mentioned above, this is one of the most useful skills you might have when working with frontend Google Tag Manager. The more you practice using CSS selectors the more easier it will be for you to add events nearly to any element on your or your client’s website.
I hope this was not too overwhelming and let me know if the comments if you’ll have any questions!
The post CSS selectors in Google Tag Manager – a practical guide appeared first on .
]]>