# GTM variables for marketers: built-in and custom

> Enable built-in variables, create Constants, Data Layer Variables, Regex Tables and Lookup Tables, and keep IDs out of hard-coded tags. Nov 2026.

Source: https://mentionx.ai/learn/gtm/gtm-variables-built-in-custom  
Author: Dipuck Jones, founder of MentionX  
Updated: 5 November 2026  
Level: Practitioner

**Variables are named values GTM resolves when tags and triggers run: page URL, click text, a Measurement ID you store once, or a field your site pushed into the data layer. Good variable design keeps containers readable and stops ID typos from shipping to production.**

> **Key takeaways**
>
> - Enable built-in variables before reinventing them with Custom JavaScript.
> - Store every ID (GA4, Ads send-to, Meta Pixel) in Constant variables.
> - Data Layer Variables should match the exact keys your developers push.
> - Regex and Lookup Tables encode marketing logic without Custom HTML soup.

*Checked 5 November 2026 (CET) against Google Tag Manager Help, Google tag platform developer docs, Google Ads Help, Analytics Help and Meta Business Help where cited. Google Tag Manager, GA4 and Ads UIs change often, so confirm labels in your own accounts. "Our view" marks MentionX opinion. Ledgerline is a fictional company used for illustration.*

## Built-in variables to turn on early

In **Variables → Configure**, enable the ones you will actually use. A practical starter set for marketing sites:

**Pages:** Page URL, Page Hostname, Page Path, Page Title, Referrer.

**Clicks:** Click Element, Click Classes, Click ID, Click URL, Click Text.

**Forms:** Form Element, Form Classes, Form ID, Form Target, Form URL, Form Text.

**Utilities:** Event, Container ID, Container Version, Random Number, Debug Mode.

**History:** History Source, New History Fragment, Old History Fragment, New History State (for SPAs).

You do not need every built-in. Enabling dozens you never reference only adds noise in Preview's Variables panel.

## Custom variable types that matter

| Type | What it does | Marketing use |
|---|---|---|
| Constant | Fixed string | `G-XXXX`, Ads `AW-XXXX/label`, Meta Pixel ID |
| Data Layer Variable | Reads a key from dataLayer | `ecommerce.value`, `lead_type`, `user_id` (careful with PII) |
| URL | Parses component of a URL | Query `gclid`, path segments |
| Auto-Event Variable | Extra detail from clicks/forms | Element attribute `data-cta` |
| Lookup Table | Maps input → output | Hostname → `production` / `staging` |
| Regex Table | Regex match → output | Path patterns → content group |
| Custom JavaScript | Function returning a value | Last resort; prefer templates |
| Google Tag: Event Settings | Reusable event parameter sets | Shared GA4 params across event tags |
| User-Provided Data | Enhanced conversions inputs | Lesson 10 |

## Naming conventions for variables

Use a prefix so Preview and the variable list stay scannable:

- `const - GA4 Measurement ID`
- `const - Google Ads Conversion ID`
- `dlv - ecommerce.value`
- `dlv - generate_lead.lead_type`
- `lut - hostname to env`
- `url - gclid`

*Our view:* if a new contractor cannot guess what `dlv - ecommerce.value` contains, your naming still works; if you have `Variable 3` and `js - stuff`, it does not.

## Data Layer Variables in detail

When the site pushes:

```
dataLayer.push({
  event: 'generate_lead',
  lead_type: 'demo_request',
  form_id: 'demo-hero'
});
```

Create Data Layer Variables with Data Layer Variable Name set to `lead_type` and `form_id` (exact keys). Version 2 of the data layer is the GTM default for modern containers; do not switch versions casually.

**Caveats.** Nested keys use dot paths when appropriate (`ecommerce.items.0.item_id` is usually the wrong approach for items arrays — ecommerce tags expect the object structure; see lesson 14). Missing keys return undefined; triggers that require a value will not match.

## Lookup and Regex Tables for environment safety

Example Lookup Table:

- Input: `{{Page Hostname}}`
- `www.ledgerline.example` → `production`
- `staging.ledgerline.example` → `staging`
- Default → `other`

Use the output in triggers or as an event parameter `env` so test traffic is obvious in Explorations. Pair with exception triggers that block Ads conversion tags when env is not production.

## Constants beat copy-paste

Every Google Ads Conversion Tracking tag needs a Conversion ID and label. Put `AW-123456789` in `const - Google Ads Account` and the label in `const - Ads Conv - Demo` (or a single `send_to` constant). When the Ads account changes, you edit one variable.

Same pattern for Meta Pixel ID and any third-party IDs.

## Custom JavaScript: when it is justified

Justified examples: normalising phone fields before enhanced conversions, deriving a content group from complex path rules, reading a first-party cookie the CMS sets.

Unjustified examples: hard-coding Marketing's opinion of channel into JS instead of using GA4 channel groups; scraping email from the DOM when a data layer field should exist; anything that duplicates a Community Template.

Custom JavaScript runs in a sandboxed way in GTM but still deserves code review. Prefer Custom Templates for reusable logic.

## How variables show up in Preview

In Preview, select an event in the left summary, open **Variables**, and confirm values at that moment. A variable can be correct on `generate_lead` and empty on `page_view` — that is normal. Debug "tag did not fire" issues by checking the variables the trigger depends on at that event.

## Worked example: Ledgerline variable set

*Ledgerline is a fictional accounts-payable software company. Details are illustrative.*

Ledgerline created twelve Constants and Data Layer Variables on day one of the GTM migration, before building tags:

1. `const - GA4 Measurement ID`
2. `const - GTM preview note` (unused in tags; stored owner Slack handle in the variable note field)
3. `const - Ads send_to - demo`
4. `const - Meta Pixel ID`
5. `dlv - lead_type`
6. `dlv - form_id`
7. `dlv - ecommerce.value`
8. `dlv - ecommerce.transaction_id`
9. `dlv - ecommerce.currency`
10. `lut - hostname to env`
11. `url - utm_campaign` (URL variable query key)
12. `url - gclid`

Tags built later reused these. When staging used a different GA4 stream briefly, they swapped one Constant and published a staging environment — no tag edits.

### Walkthrough

1. Enable the starter built-in set listed above.
2. Create `const - GA4 Measurement ID` and point your Google tag at it (update from lesson 3 if you hard-coded the ID).
3. Create `lut - hostname to env` for your real hostnames.
4. Create `dlv - lead_type` even before the push exists; it will be undefined until lesson 6–7 work lands.
5. Preview a page; open Variables on `Container Loaded` and on a click event; note how Click Text populates only on click events.
6. Add notes to each Constant naming the system of record (GA4 Admin, Ads conversions page, Meta Events Manager).

> **Pro move:** put the URL of the system-of-record screen in the variable's Notes field (GA4 stream details, Ads conversion action, Meta dataset). Audits become faster.

## Troubleshooting variables

| Symptom | Likely cause | Fix |
|---|---|---|
| Variable always undefined | Wrong data layer key or push happens after tag fires | Align key names; fire tags on the Custom Event, not All Pages |
| Click Text empty | Clicked child element without text | Use Click Classes/ID or data attribute Auto-Event Variable |
| Lookup returns default always | Hostname includes port or www mismatch | Check exact `{{Page Hostname}}` in Preview |
| Regex Table too greedy | Pattern matches multiple rows incorrectly | Order rows carefully; use anchors |
| Secret ID committed to export | Constants are in container JSON | Treat exports as sensitive; limit who can download |

## How this connects to GA4 and Ads

Variables often feed event parameters that you later register as custom dimensions in GA4 ([GA4 custom dimensions and DebugView](https://mentionx.ai/learn/ga4/ga4-custom-dimensions-debugview)). Ads conversion tags consume Constants for send_to values ([Google Ads conversions lesson](https://mentionx.ai/learn/gtm/gtm-google-ads-conversions)). Keep naming aligned so a weekly report in [n8n reporting](https://mentionx.ai/learn/n8n/n8n-reporting-ga4-google-ads) can trust field names.

## Parsing UTMs and click IDs

URL variables can read `utm_source`, `utm_medium`, `utm_campaign`, `gclid`, `gbraid`, `wbraid` and similar. Capturing them into event parameters can help debugging, but GA4 already stores campaign fields for sessions when the Google tag runs correctly. Prefer fixing collection over duplicating campaign fields on every custom event.

Where custom parameters help: capturing a first-touch promo code from the landing URL into a user-scoped dimension with a carefully designed first-wins rule — that is an advanced GA4 design, not something to hack carelessly in GTM alone.

## Auto-Event Variable attributes

If engineering adds `data-cta`, `data-plan`, or `data-article-id` hooks, Auto-Event Variables can read them on click without a full data layer rewrite. This is a pragmatic bridge during redesigns. Still document the attributes in the event dictionary so they do not rot.

## Do not store secrets in variables

API tokens, private Measurement Protocol secrets, and Meta access tokens do not belong in web container Constants. Anything in the container can appear in exports and may be visible to users with read access. Server containers and secret managers exist for a reason (lesson 17).

## Try it yourself

Replace any hard-coded Measurement ID or Pixel ID in your container with Constants. Publish. Confirm Preview still resolves the Google tag Tag ID correctly.

## Quick quiz

**1. Why prefer a Constant for a Pixel ID?**

*Answer:* Single edit surface, fewer typos, clearer audits.

**2. When is a Data Layer Variable empty in Preview?**

*Answer:* When you inspect an event that occurred before the push, or the key name does not match.

**3. What is a Lookup Table good for?**

*Answer:* Mapping known inputs such as hostname to labels like production/staging.

## What should you check before the next lesson?

- Built-ins enabled.
- IDs moved into Constants.
- You can read variable values per event in Preview.

Previous: [Triggers explained](https://mentionx.ai/learn/gtm/gtm-triggers-explained). Next: [The data layer for marketers](https://mentionx.ai/learn/gtm/gtm-data-layer-marketers). Or return to the [GTM for Marketers track](https://mentionx.ai/learn/gtm/gtm-for-marketers).

## Common questions

**Which built-ins should I enable?** Page, Click, Form, Event, and utility variables listed above; add more as needed.

**Constant vs Lookup Table?** Constant = one value. Lookup = map of inputs to outputs.

**Auto-Event variables for conversions?** Prefer data layer fields for primary conversions.

## Sources

- Google Tag Platform, [The data layer](https://developers.google.com/tag-platform/tag-manager/datalayer)
- Google Tag Manager Help, [Set up Google Analytics events](https://support.google.com/tagmanager/answer/13034206)
- All accessed 5 Nov 2026.

## Frequently asked questions

### Which built-ins should I enable?

At minimum: Page URL, Page Hostname, Page Path, Referrer, Click URL, Click Text, Click Classes, Form ID, Form URL, Event. Enable more as needed.

### Constant vs Lookup Table?

Constant holds one value (Measurement ID). Lookup Table maps inputs to outputs (hostname to environment label).

### Are Auto-Event variables enough for conversions?

Rarely for primary conversions. Prefer data layer values that mirror CRM fields.

---

Written and reviewed by Dipuck Jones for MentionX Learn. The HTML version of this page: https://mentionx.ai/learn/gtm/gtm-variables-built-in-custom
