Variables in Google Tag Manager are the "what" — they capture the values your tags send to GA4. A tag can fire on the right event at the right time, and still send no useful data if its variables are missing or wrong. That purchase event fires on every transaction, but if the value parameter is empty because nobody set up the variable that reads it, your revenue data is blank. GTM has 23 built-in variable types covering the basics: page URL, click element, referrer. But it is the custom variable types that do the real work — reading ecommerce data from the dataLayer, extracting campaign parameters from URLs, computing values from the DOM on the fly.
This guide covers the 6 most useful custom variable types with real-world examples. By the end you will know which type to reach for in any situation, how to configure each one correctly, and what to watch for when they fail silently.
What Are GTM Variables?
Variables store values that tags and GTM triggers can use. A tag uses a variable as an event parameter value — "send whatever {{DLV - Ecommerce Purchase Value}} holds as the value parameter on this purchase event." A trigger uses a variable as a filter condition — "only fire when {{Page Path}} contains /checkout." Variables are evaluated at the moment a trigger fires — not at page load. If the dataLayer push that triggers your purchase event includes a value key, the variable reads it at that exact moment.
GTM splits variables into two categories. Built-in variables are pre-built by Google and need only to be enabled: Click URL, Page Path, Page Hostname, Form ID, Video URL, and about 20 others. Enable the ones you need under Variables → Configure. User-defined variables are the ones you create. These are what this guide covers — the six types that handle everything the built-ins cannot.
The 6 Most Useful Custom Variable Types
Data Layer Variable
The Data Layer Variable reads a value from the dataLayer array. This is the most important custom variable type for ecommerce and custom event tracking. Every meaningful ecommerce event — purchase, add_to_cart, begin_checkout — carries its payload in the dataLayer, and Data Layer Variables are how you extract that payload and pass it into your tags.
Configuration: Variable Type = Data Layer Variable. Data Layer Variable Name is the key path to the value you want. Version should be set to Version 2 (the current standard).
To read the top-level value from a purchase push:
dataLayer.push({
event: 'purchase',
ecommerce: {
transaction_id: 'T-12345',
value: 129.00,
currency: 'USD',
items: [
{ item_name: 'Running Shoes', item_id: 'SKU-001', price: 129.00, quantity: 1 }
]
}
});
Set the Data Layer Variable Name to ecommerce.value — dot notation traverses nested objects. To read the first item's name: ecommerce.items.0.item_name. To read the transaction ID: ecommerce.transaction_id. The dot notation handles any level of nesting.
When a Data Layer Variable cannot find the key you specified, it returns undefined — silently. Your tag fires, but the parameter it was supposed to send is empty. Always verify in GTM's Preview mode that the variable resolves to the value you expect, not undefined.
JavaScript Variable
The JavaScript Variable executes a JavaScript snippet and returns the result. It is the most flexible custom variable type — if a value exists somewhere on the page, a JavaScript Variable can reach it. Use it for reading values from the DOM, from window-scoped globals, from localStorage or sessionStorage, or for performing calculations at the moment a tag fires.
The configuration is a function body that returns a value. To read a cart item count stored on window:
function() {
return window.cartCount || 0;
}
To read a value from localStorage:
function() {
return localStorage.getItem('user_segment') || 'unknown';
}
To extract text from a DOM element — for example, reading the product name from an h1 on a product page:
function() {
var el = document.querySelector('.product-title');
return el ? el.textContent.trim() : undefined;
}
One hard constraint: JavaScript Variables are synchronous only. No async, no await, no Promises. The variable must return a value immediately. If the data you need comes from a network request or an async API, the correct approach is a dataLayer push — read the data in your app code when it arrives, push it to the dataLayer, then read it with a Data Layer Variable.
URL Variable
The URL Variable reads a specific component of the current page URL. You choose which component: Protocol, Hostname, Port, Path, Query (the full query string), Fragment, or a specific Query Key.
The Query Key option is the most useful. It extracts a single named parameter from the query string without writing a regex. To capture the utm_source parameter from a URL like https://example.com/landing?utm_source=google&utm_medium=cpc: set Component Type to Query Key, Query Key to utm_source. The variable returns google.
The Path component is useful for trigger conditions and lookup tables — it returns just the path portion of the URL (/products/running-shoes) with no hostname or query string attached, which is usually what you want for page-type classification. The Hostname component returns just the domain (example.com) and is useful for cross-domain setups where you need to know which site a tag is running on.
Note: GTM's built-in Page URL variable returns the full URL. Built-in Page Path returns the path. The URL Variable type is for cases where you need a component the built-ins do not expose, particularly specific query parameters.
Cookie Variable
The Cookie Variable reads the value of a named browser cookie. Configuration: enter the cookie name exactly — cookie names are case-sensitive. The variable returns the raw cookie value as a string.
Useful applications: reading a consent preference stored by your CMP (Consent Management Platform) to check what the user has accepted before firing a tag, reading a first-party session identifier set by your application, or reading a custom cookie that stores information about the user's loyalty tier or membership status.
One clarification: do not use a Cookie Variable to read Google's _ga cookie. GTM's built-in variables already expose the GA client ID. The Cookie Variable is for first-party cookies set by your own application code or CMP, not for Google's measurement cookies.
If the cookie does not exist, the variable returns undefined. If you are using a Cookie Variable in a trigger condition, account for the case where the cookie is absent — a condition checking "Cookie Variable equals granted" will fail (trigger won't fire) when the cookie doesn't exist yet, which is usually the correct behavior but worth verifying.
Constant Variable
The Constant Variable stores a fixed string value that never changes. One field: the value. That is the entire configuration.
The value of a Constant Variable is not the value itself — it is the fact that you define it once and reference it everywhere. The most common use is your GA4 Measurement ID. Instead of typing G-XXXXXXXXXX into every GA4 tag in your container, create a Constant Variable named Const - GA4 Measurement ID with the value set to your ID. Reference {{Const - GA4 Measurement ID}} in every GA4 tag. When your Measurement ID changes — because you migrate properties, or you have staging and production environments — you update one variable and every tag updates automatically. Hunting through 15 tags to update a hardcoded ID is how mistakes happen.
Other practical uses: environment identifiers (production vs staging), pixel IDs for ad platforms, hardcoded currency codes, or any string that appears across multiple tags and needs to stay consistent.
Lookup Table Variable
The Lookup Table Variable maps one value to another. You define an input variable, a list of input→output pairs, and an optional default output for inputs that do not match any row. When the trigger fires, GTM reads the input variable's current value, looks it up in the table, and returns the corresponding output.
The most practical use: page-type classification. Your GA4 events need a page_type parameter so you can segment reports by content type. Configure the Lookup Table with Input Variable set to {{Page Path}}:
Input → Output
/ → homepage
/cart → cart
/checkout → checkout
/order-confirmed → order_confirmed
For path-prefix matching (all product pages, all category pages), the Lookup Table supports "contains" as the match type alongside "equals" and "starts with." Set the match type to "starts with" and add a row for /products/ → product_detail and /collections/ → collection. Set the default output to other so no path ever returns undefined.
Lookup Tables are also useful for mapping event names to human-readable labels, mapping country codes to region names, or mapping product SKUs to product categories — any situation where you have a known set of input values and want to return a transformed output.
Variable Best Practices
Name variables descriptively
A variable named DLV - value tells you the type but not what the value represents. A variable named DLV - Ecommerce Purchase Value tells you exactly what it captures, where it comes from, and when to use it. The convention that scales: [Type Abbreviation] - [What It Captures].
Standard type abbreviations: DLV for Data Layer Variable, JS for JavaScript Variable, URL for URL Variable, Cookie for Cookie Variable, Const for Constant, LT for Lookup Table. Applied: DLV - Product Name, JS - User Login Status, Cookie - Consent Preference, Const - GA4 Measurement ID, LT - Page Type. When a container has 50 variables, descriptive names are the difference between a maintainable setup and an archaeology project.
Test in preview mode first
Variables fail silently. A Data Layer Variable with a misspelled key name returns undefined. A JavaScript Variable that reaches for a DOM element that does not exist on the current page returns null. Your tag fires either way — it just sends no useful data. The event lands in GA4, the parameter is blank, and unless you notice in a report that the field is empty, you will not know until much later.
GTM's Preview mode has a Variables tab for each event in the debug panel. Click any event, then click the Variables tab — you see every variable in your container and exactly what it resolved to at the moment that event fired. Check every variable your tag uses before publishing. A variable showing undefined in Preview is a broken variable. Fix the configuration, reload Preview, confirm the value, then publish — creating a new container version with a clear description of what changed.
Avoid PII in variables
A Data Layer Variable that captures email addresses, full names, or phone numbers and sends them as event parameters violates GA4's terms of service and most privacy regulations. The violation is not in the variable existing — it is in sending PII to GA4 as an event parameter. A variable that reads user.email from the dataLayer and passes it as a parameter on a login event is exactly the pattern to avoid.
Use hashed or pseudonymous identifiers instead of raw PII. If you need to track an authenticated user, push a server-generated user ID to the dataLayer and use that. NiceLookingData's GTM audit checks for common PII patterns in variable configurations and flags any setup where an event parameter looks like it could be carrying personal information.
Frequently Asked Questions
What is a variable in Google Tag Manager?
A variable in GTM is a placeholder that holds a value your tags and triggers can use. Tags use variables to populate event parameters — for example, a purchase tag reads the order value from a Data Layer Variable and sends it as the value parameter to GA4. Triggers use variables as filter conditions — for example, "only fire when {{Page Path}} contains /checkout." Variables are evaluated at the moment a trigger fires, reading the current state of the page or dataLayer at that instant.
What is a Data Layer Variable in GTM?
A Data Layer Variable reads a value from the dataLayer array. When your website pushes ecommerce data into the dataLayer — product names, prices, transaction IDs — Data Layer Variables are how GTM extracts those values and makes them available to your tags. You configure the variable with the key path to the value you want, using dot notation to traverse nested objects: ecommerce.items.0.item_name reads the first item's name from a GA4 ecommerce push.
How do I create a custom variable in GTM?
In your GTM container, go to Variables in the left sidebar. Under User-Defined Variables, click New. Give the variable a descriptive name following the [Type] - [What It Captures] convention. Click the Variable Configuration block to choose the variable type, then fill in the type-specific fields. Click Save. The variable is now available to use in tags and triggers — reference it with double curly braces: {{Your Variable Name}}. Test it in Preview mode before publishing to confirm it resolves to the expected value.
What is the difference between built-in and custom variables in GTM?
Built-in variables are pre-configured by Google and only need to be enabled — Click URL, Page Path, Referrer, Form ID, and about 20 others. You cannot change how they work. Custom (user-defined) variables are ones you create and configure yourself. They handle values the built-ins do not expose: dataLayer payloads, specific query parameters, cookie values, DOM content, computed values, and anything that requires logic or a specific key path to extract. The built-ins cover the basics; custom variables cover everything your specific tracking implementation needs.
How do I read a query parameter with a GTM variable?
Create a URL Variable. Set the Component Type to "Query Key" and enter the parameter name in the Query Key field — for example, utm_source. The variable will return the value of that parameter from the current page URL. If the parameter is absent from the URL, the variable returns undefined. No regex required. Create one URL Variable per query parameter you need to track.
Can GTM variables read cookies?
Yes. The Cookie Variable type reads a named browser cookie. Enter the cookie name exactly as it is set — cookie names are case-sensitive. The variable returns the raw cookie value as a string. Use it for first-party cookies set by your application or CMP, such as consent preferences or session identifiers. If the cookie does not exist, the variable returns undefined.
What is a Lookup Table variable in GTM?
A Lookup Table variable maps an input value to a corresponding output value. You define an input variable (such as {{Page Path}}), a table of input→output pairs, and an optional default output. When the variable is evaluated, GTM looks up the current input value in the table and returns the matching output. The most common use is page-type classification: map specific URL paths to labels like product_detail, cart, or homepage and send that label as a page_type parameter with every event.
How do I debug GTM variables?
Open GTM's Preview mode (click Preview in the top-right corner of your container). Load the page you want to debug — Preview mode injects the GTM debug interface. In the debug panel, click any event in the left-hand event list. In the right panel, click the Variables tab. Every variable in your container is listed with the value it held at the moment that event fired. Variables showing undefined have a configuration problem — either the key path is wrong (Data Layer Variable), the DOM element does not exist (JavaScript Variable), the query parameter is absent (URL Variable), or the cookie is not set (Cookie Variable). Fix the configuration, refresh Preview, and verify the variable resolves correctly before publishing.
GTM Audit
See what your GTM variables are actually doing
NiceLookingData audits your entire GTM container — variable configurations, PII exposure, consent compliance, duplicate tags, and 40+ more checks. Connect your container and get a full report in under a minute.
Run a free GTM audit →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.
