Google Tag Manager Variables: Built-In and User-Defined
Variables are where Tag Manager gets its values: the page URL a trigger checks, the link text a click event sends, the order value a conversion tag reports. This guide covers the built-in variables Google provides for web containers, the user-defined types you can add, how lookup and RegEx tables map one value to another, and how to format values before they reach your tags.
This guide is built from Google's Tag Manager Help pages: about variables, built-in variables for web containers, user-defined variable types for web and format values in user-defined web variables, plus the other pages linked below. How to push values into the data layer and read them with a Data Layer Variable is in our GTM data layer guide. The triggers that use these variables as filters are in our GTM triggers guide.
What a variable does
Google defines Tag Manager variables as "named placeholders for values that are populated when code is run on your website or mobile app." The built-in variable Page URL, for example, returns the URL of the current page. Variables do two jobs:
- In triggers, they set the filters that decide when a tag fires, for example a trigger that fires when the URL contains a certain path. Each trigger filter is a variable, an operator and a value.
- In tags, they "capture dynamic values", such as a transaction value and product ID passed to a conversion tag.
In a tag or trigger field you reference a variable by its name in double curly braces, such as {{Page URL}}. Google says built-in variables "handle most needs for tag and trigger configurations", and you create user-defined variables for anything they don't cover.
Built-in variables
Built-in variables are ready-made: you switch on the ones you need in the Variables section, or add one from a trigger filter menu. Google's page groups the web ones like this:
| Group | Variables | Where the value comes from |
|---|---|---|
| Pages | Page URL, Page Hostname, Page Path, Referrer | The current URL and the referrer URL |
| Clicks | Click Element, Classes, ID, Target, URL, Text | Set by click triggers |
| Forms | Form Element, Classes, ID, Target, URL, Text | Set by form triggers |
| Scroll | Scroll Depth Threshold, Units, Direction | Set by scroll depth triggers |
| Visibility | Percent Visible, On-Screen Duration | Set by element visibility triggers |
| Videos | Video Current Time, Duration, Percent, Provider, Status, Title, URL, Visible | YouTube video triggers |
| History | History Source, New and Old History Fragment, New and Old History State | Set by history change triggers |
| Errors | Error Message, Error URL, Error Line, Debug Mode | JavaScript error triggers (Debug Mode reports preview) |
| Utilities | Event, Container ID, Container Version, Environment Name, HTML ID, Random Number, Analytics Client ID, Session ID, Session Number | The container, the current event and Google Analytics cookies |
Most of these read a key that a trigger writes to the data layer. Click URL, for example, reads gtm.elementUrl, and Scroll Depth Threshold reads gtm.scrollThreshold. So a click variable only has a value when a click trigger has fired. Event returns "the name of the current dataLayer event", such as gtm.js, gtm.dom, gtm.load or your own custom event name. Google's page also lists built-in variables for app containers, which this guide leaves out.
Creating a user-defined variable
Google's steps: in the left navigation click Variables, then New under User-Defined Variables, click Variable Configuration and pick a type, fill in its options, name it and save. Google suggests a name that describes the variable's job, such as "Data Layer Variable - Product Name". The web types fall into four groups:
- Navigation: HTTP Referrer, URL.
- Page variables: 1st party cookie, Custom JavaScript, Data layer, JavaScript variable.
- Page elements: Auto-event variable, DOM element, Element visibility.
- Utilities and container data: Analytics Storage, Constant, Custom event, Environment name, Google tag configuration and event settings, Lookup table, Random number, RegEx table, User-provided data, Container ID, Container version number, Debug mode.
Reading values from the page
When the value you need isn't in a built-in variable, these types read it from the page:
- URL: exposes one part of a URL. The parts are Full URL, Protocol, Hostname, Port, Path, Filename Extension, Query and Fragment. It reads the current page's URL by default; URL Source lets it parse another variable instead, such as Click URL.
- HTTP Referrer: "the URL of the previous page that the person visited". Tag Manager creates one; extra instances can expose other parts of the referrer.
- 1st party cookie: the value of a named cookie on the current domain. If there are several with the same name, the first one is used.
- Data layer: a key pushed with
dataLayer.push(). Setup and the version 1 and 2 setting are covered in our data layer guide. - JavaScript variable: a global JavaScript variable. Google suggests it when a value isn't in the data layer or the DOM but you "can find the value in the page's source code as a global JavaScript variable."
- DOM element: the text of an element, or one of its attributes if you name one, such as
data-food="cupcake". - Element visibility: whether one element is visible (True / False, with an optional Minimum Percent Visible) or what percent of it is on screen. Unlike the visibility trigger, it reports on a single element.
- Auto-event variable: details of the element behind the event, such as Element, Element Type, Element Attribute, Element Text or Element URL, plus history fragments and states.
- Custom JavaScript: "an anonymous function that returns a value". Google's example lowercases the URL:
function () { return {{url}}.toLowerCase(); }
Google points to the data layer first, then the DOM, then a global JavaScript variable. Reading the DOM or a script variable ties tracking to the page's code, so a redesign can break it without warning.
Lookup tables and RegEx tables
A Lookup Table sets its value from another variable's value. Google's example is a Conversion ID that changes by URL:
| When {{url}} contains | Set {{Conversion ID}} to |
|---|---|
| /thanks/buy1.html | 12345 |
| /thanks/buy2.html | 34567 |
| /thanks/buy3.html | 56789 |
A RegEx Table does the same with regular expressions. In Google's example, .*/page[1-3]\.html.* outputs "foo" for http://example.com/page1.html and http://example.com/page2.html#detail. Rows are checked from top to bottom and the first match wins. Set Default Value gives an output when nothing matches. Three advanced settings change matching:
- Ignore Case: on by default, so upper and lower case both match.
- Full Matches Only: on by default. The pattern must match the whole input, as if it had
^and$around it. Off, it matches anywhere in the input. - Capture Groups and Replace Functionality: lets the output use
$1,$2and so on from capture groups. Google warns that using it with Full Matches Only off "may result in unexpected behavior".
Constants, Google tag settings and other utilities
- Constant: a fixed string. Google says constants are "commonly used when there are multiple tags that use the same account number."
- Google tag: Configuration settings and Event settings: sets of parameters you can reuse across Google tags. Google's examples are a language parameter for all tags and a discount-code parameter for GA4 events. On a tag, Show inherited settings lists what came from the variable.
- Analytics Storage: reads the Google Analytics Client ID, Session ID or Session Number. Add a Measurement ID to get one session's value instead of a combined string. Google calls it a reliable way to get these IDs for uses such as the Measurement Protocol.
- User-provided data: email, phone, name and address from a form, set up automatically, manually from existing variables, or by code.
- Random number: between 0 and 2147483647. Custom event: the name of the event pushed to the data layer. Container ID, Container version number, Environment name and Debug mode describe the container that is running.
Formatting a variable's value
Every user-defined web variable has a Format Value section. Google says it helps "normalize values that are sent to your tags and reports". The options:
- Change case to lowercase or uppercase.
- Convert to number, or to true/false.
- Replace null, undefined, true or false with text or another variable.
If you pick several, they run "in the order shown from top to bottom." Converting to a number needs a decimal separator. With Period, '111,222' becomes 111222. With Comma, '111,222' becomes 111.222. Automatic (currency) treats both '123.45' and '123,45' as 123.45, but doesn't treat a separator followed by exactly three digits as a decimal point. That matters for prices sent to ecommerce or conversion tags.
Checking values in preview mode
Test variables in preview and debug mode before you publish. It opens your site connected to Tag Assistant, which shows which tags fired and why. The Debug Mode variable returns true there, and the Container Version Number variable returns the preview version number. Our basics guide covers preview, publishing and versions. To confirm a value reached Analytics, see our GA4 DebugView guide.
How we work with variables
This is our own practice, not Google's guidance:
- We switch on only the built-in variables a container uses, so the menus stay short.
- We name variables by type and content, such as "DLV - order_value" or "Lookup - Ads conversion label", in the way Google suggests.
- IDs used by several tags go in one constant or Google tag settings variable, so a change happens in one place.
- When a value can come from the data layer, we ask for it there instead of reading the DOM or a page script. That way it survives a redesign.
- Every RegEx Table gets a default value. That way a missing match shows up as a clear label instead of an empty field.
Frequently asked questions
What is the difference between built-in and user-defined variables?
Built-in variables are predefined by Google, such as Page URL, Click URL and Form ID, and you only switch them on. User-defined variables are ones you create and configure yourself, such as a Data Layer Variable, a Lookup Table or a Constant, for values the built-in ones don't cover.
Why is my Click URL or Click Text variable empty?
Click variables read values that click triggers write to the data layer, so they only have a value on a click event. Check in preview mode that a click trigger fired, and that the variable is switched on.
When should I use a RegEx Table instead of a Lookup Table?
Use a Lookup Table when you match exact values. Use a RegEx Table when one row has to match a pattern, such as several page URLs at once. RegEx rows are checked from top to bottom and the first match wins.
What does a Custom JavaScript variable need to return?
It must be an anonymous function that returns a value, for example a function that returns the page URL in lowercase. The value it returns becomes the variable's value.
Can Tag Manager convert a price string to a number?
Yes. Use Format Value and choose Convert to number with a decimal separator: Period, Comma, or Automatic (currency), which detects either separator.
For more on measurement, see our guides to Google Tag Manager basics, GTM triggers, the GTM data layer and server-side tagging.