Variables in Google Tag Manager are containers that hold values — a page URL, a click text, a product price, a user ID. They're used inside tags (to send data) and triggers (to decide when tags fire). Understanding variables is the difference between basic GTM usage and precise, powerful tracking.
Understanding GTM Variable Types
The Three Types of GTM Variables
GTM organizes variables into three categories based on where they come from and who defines them. Understanding the distinction is foundational — nearly every tracking bug we see in GTM audits traces back to a team using the wrong variable type for the job. Built-in variables are the fastest path to capturing basic page and interaction data, user-defined variables handle anything custom, and event data variables are exclusive to server-side containers.
- Built-In Variables: Pre-configured by Google. Capture page URL, click data, form data, video interactions, scroll depth. Must be enabled in Variables → Configure before they can be used in tags or triggers.
- User-Defined Variables: Custom variables you create. Nine subtypes — the most important are Data Layer, Custom JavaScript, Lookup Table, and 1st Party Cookie.
- Event Data Variables: Used only in server-side GTM to read event data forwarded from the client container. You won't encounter these until you've set up a server container.
Variable Reference by Type
Built-In Variables You Should Always Enable
GTM ships with ~30 built-in variables, but most are disabled by default to keep the variable list clean. Enable the ones below in every container you create — they cover roughly 80% of real-world tracking needs and cost nothing to leave on. Go to Variables → Configure at the top-right of the Variables page, tick the checkboxes, close the dialog.
- Page Variables: Page URL, Page Hostname, Page Path, Referrer — used in almost every tag.
- Click Variables: Click Element, Click Classes, Click ID, Click URL, Click Text — required for no-code click tracking.
- Form Variables: Form Element, Form Classes, Form ID, Form URL — required for form submission triggers.
- Scroll Variables: Scroll Depth Threshold, Scroll Depth Units — needed for custom scroll tracking beyond the default 90%.
- Utility: Container ID, Container Version, Debug Mode, HTML ID — invaluable for debugging and conditional tag firing.
User-Defined Variable Types: Data Layer Variable
The Data Layer Variable is the single most important user-defined variable type and should be your default choice for reading any custom value from the page. It reads values from the window.dataLayer object — a global array that both the GTM snippet and your site's code can push into. Data Layer Variables are the GTM team's recommended pattern because they respect event timing, survive SPA navigation better than DOM reads, and make your tracking independent of HTML structure.
If your developer pushes dataLayer.push({event: 'purchase', user_type: 'premium', cart_value: 129.50}), you create three Data Layer Variables (one per key) to access those values in tags. Two configuration details catch teams:
- Data Layer Version: Leave as "Version 2" — Version 1 is legacy and handles nested objects poorly.
- Default Value: Set a sensible fallback (e.g., empty string) so downstream tags don't receive
undefined.
User-Defined Variable Types: JavaScript, Custom JavaScript, DOM Element
Three variable types read data directly from the page rather than the data layer. Each has a specific use case, and each has a specific failure mode. In general, prefer Data Layer Variables whenever possible — these three types are more fragile because they depend on the site's current HTML or JavaScript state at the moment the variable is evaluated.
- JavaScript Variable: Reads a global JavaScript variable. Example: if your site sets
window.userId = '12345', a JavaScript Variable with keyuserIdcaptures it. ⚠️ Reads at evaluation time, so timing-sensitive values can be empty. - Custom JavaScript: Runs an anonymous function and returns the result. Useful for computed values like extracting a product ID from a URL path or formatting a date. Wrap in
function() { return ...; }. - DOM Element: Reads an HTML element's content by ID or CSS selector. Use sparingly — DOM reads are the most fragile variable type and break whenever a developer tweaks markup.
User-Defined Variable Types: Lookup Table, RegExp Table, 1st Party Cookie
These three variable types handle mapping and storage scenarios that the others don't cover well. Lookup tables turn raw values into human-readable categories; regex tables do the same for pattern-matched values; first-party cookie variables read persistent state from the browser without JavaScript.
- Lookup Table: Maps exact input values to output values. Example: map page paths to content categories —
/blog/*(exact path start) → "Blog,"/products/*→ "Products." Ideal for enriching GA4 events with human-readable labels. - RegExp Table: Like Lookup Table but with RE2 regex pattern matching. More powerful when exact matches aren't possible — e.g., matching any product page under
^/products/([^/]+)/. - 1st Party Cookie: Reads a first-party cookie value by name. Useful for grabbing consent status (
_consent_v2), A/B test variants, or user preferences stored in cookies by your CMS or consent manager.
Practical Patterns
5 Must-Have Custom Variables for Every Container
These five custom variables are the ones we add to nearly every GTM container we set up or audit. They dramatically improve GA4 reporting quality by creating reliable dimensions you can filter, segment, and compare on. Set them up once at the start of a project and they'll power dozens of tags downstream without further maintenance.
- Content Group Variable: Lookup Table mapping page paths to content categories (Blog, Product, Support, Legal, Account).
- Logged-In Status: Data Layer Variable reading
user_logged_in(true/false) — required for segmenting logged-in vs anonymous sessions. - User Type: Data Layer Variable reading
user_type(free, premium, enterprise) — essential for SaaS analytics. - Page Type: Lookup Table or Custom JavaScript categorizing pages (homepage, PDP, PLP, checkout, thank-you).
- Debug Mode Flag: Custom JavaScript that returns true when URL contains
?debug=true. Use this in tag conditions to silence noisy tags during QA.
Variable Scoping and Timing: Why Your Variables Are Sometimes Empty
The #1 GTM bug we debug on client audits is a variable returning empty or undefined when it should have a value. This almost always comes down to timing: variables are evaluated at the moment they're needed (when the tag fires), not when they're defined. If your dataLayer.push happens after the tag fires, the Data Layer Variable reads empty. The fix is to gate the tag on a custom event trigger that only fires after the data is available.
- Developer pushes event:
dataLayer.push({event: 'user_data_ready', user_type: 'premium'})as soon as user data loads. - Create a Custom Event trigger in GTM for
user_data_ready. - Attach your tag to this custom event trigger (not Page View, not DOM Ready).
- Now the Data Layer Variable is guaranteed to have a value because the event is only dispatched once the data exists.
GTM Variable Check
NiceLookingData audits your GTM container for orphaned variables, data layer configuration issues, and missing variable connections. Run a free GTM audit.
Frequently Asked Questions
What are GTM variables?
GTM variables are containers that hold values — things like a page URL, a click's text, a product ID from the data layer, or a user's login state. They serve two purposes: passing data into tags (so a GA4 event tag can send the current product price) and controlling when triggers fire (so a trigger only fires when a click URL contains "/checkout"). Without variables, every tag would be hardcoded and every trigger would be static.
What are the types of GTM variables?
GTM has two main categories. Built-in variables are preconfigured by Google and capture page data (URL, path, hostname), click data (element, text, classes, URL), form data, and scroll depth — you enable the ones you need under Variables → Configure. User-defined variables are custom ones you create. The most important user-defined subtypes are: Data Layer Variable (reads from window.dataLayer), Custom JavaScript (runs a function and returns its result), Lookup Table (maps exact values to outputs), RegExp Table (maps pattern-matched values), JavaScript Variable (reads a global JS variable), and 1st Party Cookie (reads a browser cookie).
What is a dataLayer variable in GTM?
A Data Layer Variable reads a specific key from the window.dataLayer array. When your site pushes dataLayer.push({event: 'purchase', order_value: 99.99}), a Data Layer Variable configured with the key order_value will capture 99.99. This is the recommended way to pass custom data into GTM because it's event-timed and doesn't depend on HTML structure.
What is the difference between built-in and user-defined variables in GTM?
Built-in variables are maintained by Google and capture browser/DOM state at standard interaction points — page URL, click element, form data. They require no configuration beyond enabling them. User-defined variables are entirely custom — you define their type, their source (data layer key, JavaScript expression, lookup table), and their default value. Built-in variables handle what you need out of the box; user-defined variables handle your specific business data.
How do I create a GTM custom JavaScript variable?
Under Variables → New → Variable Type → Custom JavaScript. The variable must be an anonymous function that returns a value: function() { return document.title; }. Custom JavaScript variables are powerful — they can read DOM state, parse URLs, extract values from JSON strings, or call other GTM variables — but they execute on every page and can fail silently if JavaScript on the page errors. Test in Preview mode and always include error handling for null or undefined cases.
What is a GTM 1st party cookie variable?
A 1st Party Cookie variable reads the value of a specific browser cookie by name. You configure it with the cookie's name and GTM returns its current value. This is useful for reading consent status stored by your CMP (e.g., _consent_v2), A/B test variant assignments, or user preferences that your server sets as cookies. Unlike a Data Layer Variable, it doesn't require developers to push data — it reads whatever the browser already has.
When should I use a GTM lookup table variable?
Use a Lookup Table when you want to map a raw value to a human-readable category. The most common use case: map page paths to content categories — if the current page path matches /blog/, return "Blog"; if it matches /products/, return "Product". This enriches your GA4 events with meaningful dimensions without requiring developers to push additional data. Use RegExp Table when exact matches aren't sufficient and you need pattern matching.
What is the GTM URL variable?
The URL variable is a built-in variable that parses the current page URL and lets you extract specific components: the full URL, the protocol, the hostname, the path, a specific query parameter, or the fragment. For example, configuring it to capture the query parameter utm_source gives you the UTM source from the URL. The URL variable is particularly useful for trigger conditions — you can fire a tag only when the URL contains a specific path or query string value, without writing Custom JavaScript.
Analytics consultant turned founder. After years running the same GA4 and GTM audits across client engagements, Ludde built the audit into a product — so the pattern-matching takes a minute, not a meeting. More about Ludde →
Check your GTM container.
Upload your GTM export or connect live. Our auditor checks 44 best practices and gives you actionable fixes.
