Last Modified on September 4, 2024
If you have come across tag management systems (TMS) like Google Tag Manager, then you would know that it has three major building blocks that work together to track events on your website/app.
These are called tags, triggers, and variables. Now, there’s a chance at times that you can create a tag without using a variable, but it’s rare when the event name is enough.
In most cases, you do need variables that provide additional detail with the events you’re tracking, but what exactly are these variables in GTM and how can they be used? We are going to cover these topics including the following in this post:
- What are Google Tag Manager Variables?
- Variable Types in Google Tag Manager
- Best Practices for Google Tag Manager Variables
Let’s dive in!
What are Google Tag Manager Variables?
When the code runs on your website or app and certain values are populated, variables are used to ‘store’ those values.
They can be used in tags to get more context with values, like the text of the CTA, and transaction ID, or in the triggers to specify a filter condition on which a tag should fire. Here are two quick examples:
- For Tags: Use a ‘Click Text’ variable to capture the value of the text of the button clicked.
- For Triggers: Fire a PageView trigger when the ‘Page Path’ variable contains /thank-you.
Variables are quite helpful in passing dynamic values. Without variables, we would have to get the same value as ‘unique’ every time, which can be repetitive and messy.
In GTM’s context, variables can be used where you can use this syntax {{variable name}}, i.e., using two opening and closing curly brackets while using the name of the variable as it’s available in GTM, or saved by you, e.g., {{Click Text}}.
You cannot invoke triggers as conditions with these brackets because they are already available as drop-down components of setting a condition.
See this example where Click Classes is the condition we are using to filter on that it contains the add_to_cart_button classes.
Now, where you see the value of the add_to_cart_button is a field where you cannot use the curly brackets method and it doesn’t make much sense because you’re already using a variable to set the conditions.
There’s another cue for you to know where you can use these curly brackets to invoke a variable and that’s the little variable icon next to the input field as shown below.
So you can either click on the icon and select from the list of variables available in the container or create a new one and it will be added here.
The other method is that you can enter the two opening curly brackets (as shown in the Event Name field) and you will see a drop-down list of all the variables available to choose from as you enter the name of the variable.
It will only show the ones that match it.
The {{variable name}} can also be used in two other places because you can write code there and reference the existing variables:
- Custom HTML Tags
- Custom JavaScript VariableÂ
Even though the variables can be accessed from the tags and triggers, they have their section on the left side under… Variables.
Variable Types in Google Tag Manager
There are two main categories in which variables are defined:
- Built-in Variables
- User-defined Variables
As the names suggest, the built-in variables are ready to be used without any additional configuration, whereas the user-defined variables have to be configured by you.
Each of these categories has its types of variables which are categorized depending on where they are available to store values or their use case.
Let’s start with the built-in variables.
1. Built-in Variables
When you create a new container and go to the Variables page from the left side, you will see that there are only a handful of variables available.
This does not mean you don’t have any more built-in variables, but they just need to be enabled by clicking on the Configure button in the top right corner.
This will open a right sidebar interface where you can check the variables you want to enable.
This leads to the nine types of built-in variables available that we are going to explore next. These are:
- Pages
- Utilities
- Errors
- Clicks/Forms
- History
- Videos
- Scrolling
- Visibility
1. Pages
As you might have seen in the screenshot above, there are four variables under Pages which are all related to the URLs albeit in different manners when it comes to returning the values.
- Page URL – This variable returns the entire URL of the current page but without any hash fragments, e.g., https://measureschool.com/measure-masters?signup=true
- Page Path – Unlike the entire URL, this variable only returns the path of the current page URL, e.g., /measure-masters.
- Hostname – As the name implies, this variable returns only the hostname of the current page, e.g., measureschool.com without any protocol or other info in the URL.
- Referrer – With this variable, you get the full URL of the referrer page which is the previous page, e.g., https://measureschool.com/ (homepage) is the referrer from where people might be going to pages like https://measureschool.com/measure-masters?signup=true.
All of these variables return ‘string’ as their data type.
2. Utilities
These are a group of different variables that can be used to return values that can be useful in various ways which are quite subjective and situation-dependent. They are a mix of string and number data types.
- Event – It returns the string value of the current event key’s name in the dataLayer, e.g., gtm.js, gtm.load, and any other custom event names being pushed into the dataLayer.
- Environment Name – Also a string data type, this variable returns the name of the environment currently being previewed whether it’s with the Share Preview link or the environment’s container snippet.
- Container ID – This is the public ID of your GTM container being returned, e.g., GTM-N26ZWJJF as a string.
- Container Version – It returns the string containing the current version of the container, e.g., QUICK_PREVIEW, although we would expect to see the published version number of the container here.
- Random Number – This returns a random number between 0 and 2147483647.
- HTML ID – It is used for tag sequencing and returns the identifier of a custom HTML tag for that purpose.
3. Errors
These variables return different types of values but are related to errors and debugging.
- Error Message – Returns the string containing the error message when we use the Javascript Error trigger by accessing the gtm.errorMessage in dataLayer.
- Error URL – Also returns the string containing the URL where the error occurred when we use the JavaScript Error trigger. It accesses the gtm.errorUrl key in dataLayer.
- Error Line – Number of the line in the file where the error occurs when using the JavaScript Error trigger by accessing the gtm.errorLine key in dataLayer.
- Debug Mode – It returns ‘true’ when your GTM container is in preview mode.
The next type of built-in variables is used quite frequently so they should be enabled when a new container is created.
4. Clicks / Forms
We’ve added clicks and forms together here because both of the types access the same keys in the dataLayer. The only difference is in their names but their values are the same.
- Click / Form Element – These variables access the gtm.element key in the dataLayer which returns the whole HTML aka DOM element as an ‘object’ that is clicked.
- Click / Form Classes – Accessed through the gtm.elementClasses key in the dataLayer, these variables return a string containing the classes attribute of the DOM element that is clicked on.
- Click / Form ID – These variables return a string containing the ID attribute of the clicked DOM element. They are retrieved from the gtm.elementId key.
- Click / Form Target – Returns a string with the target attribute value of the element by accessing the gtm.elementTarget key.
- Click / Form URL – These return a string value in the href attribute of the clicked DOM element or action attribute via the gtm.elementURL key in dataLayer.
- Click / Form Text – Returns a string contained in the innerText attribute value of the clicked element via gtm.elementText key.
They will only return values once click / form triggers are being used so merely enabling them won’t be enough.
5. History
All the history variables can be used with a single-page application (SPA) website when using the History Change trigger. These are:
- New History Fragment – Accessing the gtm.newUrlFragment key in the dataLayer, it returns a string with the new fragment (hash) portion of the page’s URL after the history change event, e.g., #sign-up-from.
- Old History Fragment – Accessing the gtm.oldUrlFragment key in the dataLayer, returns a string with the old fragment (hash) portion of the page’s URL after the history change event.
- New History State – This variable returns the state object that the page pushes into the history which causes the history event, i.e., after pushState() occurs. It accesses the gtm.newHistoryState key.
- Old History State – This variable returns the old state object that was active before the history change event occurred through the gtm.oldHistoryState key in the dataLayer.
- History Source – It shows a string value through the gtm.historyChangeSource event in dataLayer that initiates/causes the history change (e.g., pushState or popState).
6. Videos
These variables return different data types depending on the variable and can be quite useful for tracking video content. Most of these variables only work with the YouTube Video trigger, so only for YouTube videos.
- Video Provider – Returns a string value with the provider’s name through the gtm.videoProvider event. It currently only supports YouTube.
- Video Status – It returns a string value that shows the status of the video e.g., play, pause, progress, complete, etc. via the gtm.videoStatus event in dataLayer.
- Video URL – Returns a string with the URL of the video being played. It accesses the gtm.videoUrl key.
- Video Title – It accesses the gtm.videoTitle key to return a string with the title of the video.
- Video Duration – Returns an integer value that shows the total duration of the video in seconds through the ​​gtm.videoDuration key.
- Video Current Time – Returns an integer value that shows the current time in seconds when a video event occurs through the gtm.videoCurrentTime key in the dataLayer.
- Video Percent – Returns an integer value between 0-100 through gtm.videoPercent key in the dataLayer to show how far a user has progressed in the video.
- Video Visible – Returns boolean values (true/false) depending on when the video is visible in the viewport. It accesses the gtm.videoVisible key.
7. Scrolling
All the scrolling variables help provide more info when using the Scroll Depth trigger in GTM. These are:
- Scroll Depth Threshold – Returns the integer value from 0-100 for percent, whereas for pixels it will be as per specified values – depending on how the trigger is configured. It accesses the gtm.scrollThreshold key in dataLayer.
- Scroll Depth Units – It accesses the gtm.scrollUnits key in dataLayer showing the string value of unit, i.e., percent or pixels which is chosen when setting up the scroll depth trigger.
- Scroll Direction – Returns the direction of the scroll as a string, i.e., vertical or horizontal via the gtm.scrollDirection key depending on which direction is chosen with the scroll trigger.
8. Visibility
These variables are available when the element visibility trigger is used. They are:
- Percent Visible – Returns integer value between 0-100 to indicate how much of the selected element is visible in the viewport. It is accessed with the gtm.visibleRatio key.
- On-Screen Duration – This also returns an integer value, but in milliseconds, to indicate for how long the selected element is visible in the viewport after the trigger fires. It is accessed via the gtm.visibleTime key in dataLayer.
This completes the list of built-in variables for web containers only because there are different built-in variables for AMP, iOS, and Android containers.
2. User-Defined Variables
As the name suggests these are defined by you, the user, as most of these variable types give room for customization. The following Format Value options are available for most of the variables but we’ll mention where they are not:
Surprisingly, some of the variables already available as built-in are added here again, which makes them redundant, but we’ll get to them as we go through them.
So including these redundant ones, there are in total five types of user-defined variables:
- Navigation
- Page Variables
- Page Elements
- Utilities
- Container Data
Each of these types has different variables under them, so it will take a bit of time to get to the finish line.
1. Navigation
Two variables under this category are available as built-in ones. But here they are an extension of those due to available customizations, and you can get a lot more done with those.
- HTTP Referrer – The variable returns the referrer, i.e., the previous page. Still, you can customize it to get seven different parts of the URL like the Full URL, Protocol, Hostname, Port, Path, Query, and Fragment.
- URL – This variable can be customized to expose all the parts of the URL just like the HTTP Referrer, with the addition of the Filename Extension. So in total, there are eight parts of the URL.
Let’s have a quick look at each one of these:
- Full URL provides the complete URL excluding the hash fragment.
- Protocol exposes the protocol of the URL e.g. ‘https’, ‘http’.
- Hostname returns the hostname of the URL but it can be further customized to strip the ‘www.’ part which can be handy in case of a sub-domain, e.g., www.measureschool.com will become measureschool.com
- Port can be used to get the port number used in the URL. If there’s none, then it returns the default values, i.e., 443 for HTTPS and 80 for HTTP.
- Path only returns the path of the URL excluding any fragment or query, but it can be customized to strip the default pages from the path, e.g., if the default page is ‘index.html’ and the URL is ‘https://measureschool.com/x/index.html’, the variable’s value will be ‘/x/’.
- Query returns the value of the specified key without the leading question mark (?), e.g., if the key is a test for this URL https://measureschool.com/?test=value&measure=masters, then it will return ‘value.’ But if no query key is specified, then it will expose the whole query string, i.e., test=value&measure=masters.
- Fragment exposes the URL’s fragment without the leading hash (#), e.g., https://measureschool.com/?test=value#sign-up will return ‘sign-up’.
- File Extension (only for URL variable) returns the extension of the file in the URL, e.g., .pdf, .jpg, etc.
One more setting that is available only for the URL variable components is that you can choose any other source for the URL variable. Otherwise, it selects the default value retrieved from document.location.
2. Page Variables
These four are about what happens on the page and they all work differently. Let’s see how:
- 1st-Party Cookie – It returns the first value it finds for the matching Cookie Name you specify. For instance, if you have a cookie named ‘MyAds,’ then you can access its value by entering this name in the ‘Cookie Name’ field when saving this variable.
- Custom JavaScript – This is one the most flexible variables because anything that won’t work with other types of variables can be stored/returned with this variable, as long as you know some JavaScript. It can also reference the different variables in your container.
The value of this variable is set to the result of an anonymous (empty) JavaScript function, so it should always have the function() part and it should be completed with a ‘return’ statement. Here’s how it would look like if we want to get the current page’s URL:
function() {
return window.location.href;
}
- Data Layer Variable – This is another versatile variable that only works to get the value of the dataLayer events aka keys. It returns the most recent value that is pushed for the key in GTM’s internal data model.
DataLayer events are pushed via dataLayer.push() method. You can choose from two versions. Version 1 allows you to access keys and values with dots in names, e.g., dataLayer.push(“variable.name”: “value”) will interpret the name of the key as “variable.name”. So, it’s quite limited.
Version 2 allows you to access the nested values of arrays and objects using the dot notation. It’s easy to use the square brackets for arrays if you’ve previously worked with some code to access the array values, but it’s not the case when using the dataLayer variable. For instance, it will be items.0.id not items[0]name.
You can also set a default value when no matching variable is found. If it’s not set, it will return undefined when no matching variable is available.
- JavaScript Variable – Returns the value of the global JavaScript variable you specify. This is not to be confused with the Custom JavaScript variable which works with an anonymous function. It can retrieve values stored in the page’s source code as a global JavaScript variable, especially when other variables aren’t useful. If no matching variable is found, it returns ‘undefined’.
3. Page Elements
Three variables can be used to access the information about different page elements. These are:
- Auto-Event Variable – It can be used to return the value of the target element based on auto-event actions, e.g., clicks, element visibility, form submissions, etc. and it can access 13 variable types. So, it has a very wide reach. These are:
- Element
- Element Type
- Element Attribute
- Element Classes
- Element ID
- Element URL
- Element Text
- Element Target
- History New URL Fragment
- History Old URL Fragment
- History New State
- History Old State
- History Change Source
You have already read about these variables in the Clicks/Forms and History sections of the built-in variables above, so they do the same job. E.g., to get the element ID, it would access the gtm.elementId key in the dataLayer.
Here you can set a default value if no matching variable is found. Otherwise, you will see ‘undefined’. Other than that, you should be able to use the built-in alternatives.
- DOM Element – This variable type can return the text of the DOM element or the value of an element’s attribute based on how you set it up. You have to choose a Selection Method based on ID or CSS Selector to target an element.
It can be useful to access text or attribute values of any element to be sent with an event or used in a trigger, i.e., fire when a certain element or attribute is found on the page.
- Element Visibility – This is a combination of the two built-in variables with more bells and whistles. It returns True/False values to signal if the element was in the user’s viewport or the percentage of how much it was viewed. This output type can be chosen in the settings.
If you choose the True/False method, then you also have to specify how much an element should be visible to return ‘True’. You can target the element by ID or CSS selector like the other two variables in this category.
4. Utilities
There are 11 User-defined variables under utilities.
- Constant – The value is set to the string value that you specify. It’s quite useful if there are values you need to use in multiple places, as you can simply use this variable next time, e.g., to save your GA4 or GAds tracking ID.
- Custom Event – This is one of those redundant variables that is already available as a built-in ‘Event’ variable. In other words, you don’t need it if you can use the built-in one.
- Environment Name – This is another redundant variable that returns the same value as the built-in variable of the same name, which means you have to use this either.
- Google Analytics Settings – This variable is a remnant of Universal Analytics, so it will be phased out eventually since UA is no more.
- Google Tag: Configuration Settings – This variable can be used to store configuration settings that you want to send to GA4 every time your config tag loads, e.g., language as a parameter.
- Google Tag: Event Settings – This variable can be used when you want to send any parameters or user properties with multiple events. Rather than adding a parameter/property to each event separately, you can now simply reuse the event settings variable.
- Lookup Table – This uses a source variable from your container and then returns values based on what you choose by using the logic. That is, if the selected variable returns XYZ value, turn it into ABC.
For instance, if your Click Text variable returns mens-shoes and womens-shoes, then you can specify to change them into Men Shoes and Women Shoes when these values are returned.
You can also set a default value if these two are not found, which in the above example, we’ve kept {{Click Text}} so we can find out what other values are there, or we could simply say ‘No match’ or anything that makes sense for internal users.
This is a good way to show clean and readable data in GA4 or any other end-point you have.
- Random Number – This is also a redundant variable because a built-in one already exists. Both of them return a random number between 0 and 2147483647.
- Regex Table – This variable works similarly to how the lookup table works, but can do a lot more because the lookup table works based on an exact match. Whereas with regex, you can match many complex patterns.
It also has some additional settings that can be configured to change how it works. You can see it in action in our post about How to Set Up Google Analytics 4 Content Groups.
- Undefined Value – It only has one job and that is to return ‘undefined’ values. So, there’s no customization available whatsoever. Therefore, it’s odd that it’s not part of the built-in variables. It can be used in triggers where if the value is ‘undefined’ then the trigger fires/doesn’t fire.
- User-Provided Data – This has been added recently and stores user contact information from your website like name, email, phone, and address to send to other products, mainly to set up enhanced conversions for Google Ads. There are three types of configurations to collect the data:
- Automatic – Detects and collects the relevant email address patterns found on the page. But you can exclude certain elements with CSS selectors.
- Manual – With this configuration, you have to select the variables from where it should retrieve user-provided data. None of the fields are required, so you can pick and choose what you want.
In the Name and address settings, you can choose what granular data to collect, i.e., Name, Surname, Street, City, Region, Country, and Postcode.
- Code – This is also a manual way of collecting the data by referencing a Custom JavaScript or Data Layer variable that collects the information you’re looking for. But in this case, you can only select one variable as a data source.
5. Container Data
There are three variables in this category:
- Container ID
- Container Version Number
- Debug Mode
If the names sound familiar, then it’s because they are already covered in the built-in variables section under Utilities and Errors.
The only customization available is the Format Value part. So these are another set of redundant variables that we are not sure why they are added separately again under user-defined variables.
Best Practices for Google Tag Manager Variables
The best practices below can help you keep the container clean and organized and will help with tag management, especially when things are too busy.
- Naming conventions – This is a recurring topic for GTM whether it’s the container, workspaces, tags, triggers, or variables. It’s important to have set naming conventions that are followed by everyone who works in your container.
- Dependability – When variables are trying to access other data sources that aren’t ready/available yet, the variables won’t work. So, it’s important to keep that in mind when using any type of variable.
- Use Built-in Variables – Where possible and available, you should use the built-in variables, especially if you’re tempted to use the Custom JavaScript variable.
- Error Handling – Implement proper error handling within custom JavaScript to avoid issues if the code fails. For example, wrap your code in a try-catch block.
- DataLayer Variables are Your Friend – They are reliable and easy to use, so where possible, you should use them. But if you’re part of dataLayer creation, you’d want to communicate to the devs that it should be done in a structured manner, so using dataLayer variables is easy.
- Avoid Duplication – Reuse variables whenever possible for the same purpose. It keeps the container clean and avoids redundancy. You should also reference other variables if needed for the same purpose.
- Sensitive Data – Avoid saving any sensitive info in variables, as it’s not a good practice and can cause legal issues.
- Site Performance – Having so many variables can impact the performance of your site’s speed, especially with the Custom JavaScript variable. So use them carefully.
- Documentation – There should be comprehensive documentation for your GTM configuration including variables. It can be tedious but still is worthwhile.
This list might not be exhaustive, but it can put your GTM container on the path to efficiency and easy management.
Summary
This was quite a long post and might be a little overwhelming, but it deserved that much space because we covered a lot starting from what are Google Tag Manager variables and the two major types of variable categories, i.e., built-in and user-defined.
We then looked into the different types of each of them. There are some redundant variables under the user-defined category which doesn’t make much sense. So, you should use their built-in counterparts wherever possible.
Each type of variable available also shows their potential use case.
Some have a very specific use, while others are quite versatile, and knowing this will help to know where and how they can be used. Variables are a major part of using GTM, so learning about them means you’re halfway there!
Finally, we looked at some best practices that can help us ensure that our GTM is organized, efficient, and easy to manage.
Since this blog covered a lot of variables, chances are you might be a little confused. Don’t worry as you won’t need to use them all at once anyway.
That’s it for variables but another important part of working with GTM is using triggers i.e. when should your tags fire? We cover all about triggers in the A Complete Guide to Google Tag Manager Triggers post.
Let us know in the comments below what are your top variables and why!
In the regex table variable you suggest using page path when creating variables for a content group
The one challenge with that if the URL contains query strings, they won’t get picked up, so I recommend using Page URL instead as it contains everything
yea, good call
Hello, Thanks for that valuable information. Is there any way I can retrieve the value of a cookie with the 1st party cookie, in the case of a dynamic cookie name ? >>> My GDPR consent tool issues a different version of the cookie name (incremented with each update of the consent & pixels) like gdpr-43 (then gdpr-44). As I want trigger based on this 1st party cookie, what can I do to make sure I always retrieve the name of the “latest” cookie, to use it for my cookie name variable in the setup of the 1st party cookie… Read more »
I guess you could try to use custom JavaScript to make it dynamic. But you’d definitely need some JS experience for that
Can I populate the result value of a variable in GA. For example, I want to know what my users are searching for on a map and I can’t do it with the search of GA. At the moment, what users are searching is populating as you can see attached as an
Click Text Auto Event Variable a value comes up which is the one I want to populate in GA in order to know which addresses they are searching from our website.
Basically I want to put on my dashboard with a widget the results Value of that Variable
I’m looking for a variable where the format is a number. Is there an easy way to change the format from a string to a number? I would like to change the price (it must be a number) of a ecommerce-Datalayer without building a new datalayer.
I’ve had a similar question and seems there is no dedicated Number built-in GTM variable. So, eventually create another variable of Custom JavaScript type and just converted the
price
variable to integer/float depending on what the input is, basically this snippet:function(){
return parseFloat({{price}});
}