Value Variables
Value Variables
GTM’s UI assumes everything is a string. Type true in a tag field, get “true” back. Try to put a single space as a separator, watch GTM strip it. Type null, get “null”. The Value category fills the gaps GTM’s UI hides — typed literal constants the editor won’t let you type, value substitution variables that go beyond Format Value, and the function composition primitives that the rest of the framework runs on. This is the meta-category that makes the others work.
Why this category exists
Section titled “Why this category exists”GTM’s interface treats every configuration field as a string-typed input. That’s a sensible default — but it has consequences:
- You can’t type a literal boolean. If a tag expects the boolean
true, typingtruegives the destination the string“true”. - You can’t type whitespace. GTM’s UI strips leading and trailing whitespace from configuration fields on save. No way to set a separator to a single space.
- You can’t type a literal null or empty array. The literal value
nullbecomes“null”. Trying to specify an empty array gives you the string”[]”. - RegEx Tables stop at the first match. If one input legitimately maps to multiple outputs — like an event that should fire several Facebook pixels — the native variable can’t express it.
- Format Value covers the basics, not the chains. GTM’s built-in Format Value handles
null → Xandundefined → X, but only one substitution per variable, and it can’t be chained through Apply mode.
The Value category replaces these gaps with named templates. true means the boolean true. space means the literal character ” ”. nullTo chains into Apply mode like every other variable.
Three jobs: constants, substitution, composition
Section titled “Three jobs: constants, substitution, composition”The category serves three related but distinct functions:
Inject values GTM’s UI hides
Literal true, false, null, NaN, 0, empty string, empty array, empty object, and even a single space — every primitive GTM’s editor won’t let you type as-is.
Convert null, undefined, falsy to defaults
Granular control over which input states get replaced. nullTo, undefinedTo, falsyTo, falseTo, and mapTruthiness each target a specific failure mode. More flexible than GTM’s native Format Value.
The framework’s wiring layer
apply and applyChain turn variables into chainable functions. identity, not, and filterValue are the small primitives the larger templates compose against.
Plus extended RegEx Tables — regexTableLookupAll and regexTableLookupCallback — that fix the limitations of GTM’s native RegEx Table variable.
The variables — at a glance
Section titled “The variables — at a glance”Twenty-four variables across four hero subgroups plus introspection primitives.
true.falseReturns the literal boolean false.nullReturns literal null — not the string “null”.NaNReturns literal NaN.zeroReturns the number 0.spaceReturns a literal single space character — survives GTM’s whitespace stripping.emptyStringReturns "" — useful as an explicit fallback target.emptyArrayReturns [] — for tag parameters expecting empty arrays.emptyObjectReturns — for object-typed defaults.emptyObjectArrayReturns [] — common GA4 ecommerce empty-state shape.Inject typed constants GTM’s UI won’t let you type
Section titled “Inject typed constants GTM’s UI won’t let you type”The most reliable way to discover this category is to spend an hour fighting GTM’s whitespace stripping. You configure a join operation with a space separator. You type a single space. You save. You preview. No spaces. GTM stripped it.
GTM’s UI strips leading and trailing whitespace from configuration fields on save. The only workaround is a Custom JavaScript variable that returns ” ”. Or — the space variable.
| Field | Value |
|---|---|
| Input 1 | {{DL - first_name}} |
| Input 2 | {{DL - last_name}} |
| Input 3 | {{DL - title}} |
| Separator | {{space}} |
“Jane Doe Engineer” — with actual spaces, not concatenatedThe same gap exists for every primitive type. true and false return the literal booleans. null sends actual null rather than the string “null”. The empty-collection constants — emptyArray, emptyObject, emptyObjectArray — return the actual empty data structure.
Why emptyObjectArray? GA4’s ecommerce.items field is the canonical example of “should be an array of objects, but might be empty.” Sending [] works for some destinations; sending [] matches the shape that other destinations expect. Both empty constants exist because both shapes show up in real implementations.
Substitute null, undefined, falsy with defaults
Section titled “Substitute null, undefined, falsy with defaults”GTM ships with Format Value that handles basic substitutions. It works for the simplest cases. It runs out of room when you need more flexibility.
”The Format Value option is a very useful addition to Google Tag Manager’s arsenal. I only hope the number of available formatting options is increased in the future.”
The Value category’s substitution variables are the answer. They run as Apply-mode chainable functions. They handle distinct failure modes separately.
| Variable | Replaces | Pass-through |
|---|---|---|
nullTo | null | Everything else |
undefinedTo | undefined | Everything else |
falseTo | false | Everything else |
falsyTo | 0, "", null, undefined, false, NaN | Truthy values |
| Field | Value |
|---|---|
| Input | {{DL - revenue}} |
| Fallback value | {{zero}} |
0 if input is null, undefined, empty string, NaN, false, or 0; otherwise passes input throughMap truthy and falsy values to custom outputs
Section titled “Map truthy and falsy values to custom outputs”Sometimes you want to convert a boolean signal into something more useful. A subscriber flag needs to become a string label for a GA4 custom dimension.
| Field | Value |
|---|---|
| Input | {{DL - is_subscriber}} |
| If truthy | ”subscriber” |
| If falsy | ”visitor” |
“subscriber” for any truthy input; “visitor” for any falsy inputCast user-typed strings to typed values with parseValue
Section titled “Cast user-typed strings to typed values with parseValue”GTM stores everything typed into a configuration field as a string. parseValue detects the intended type from the string content and returns the typed primitive.
| Input string | Returned value | Type |
|---|---|---|
”42” | 42 | number |
”3.14” | 3.14 | number |
”true” | true | boolean |
”false” | false | boolean |
”null” | null | null |
”hello" | "hello” | string (passthrough) |
Get all matching pixels for an event with regexTableLookupAll
Section titled “Get all matching pixels for an event with regexTableLookupAll”GTM’s native RegEx Table variable returns the first matching row’s output and stops. regexTableLookupAll returns every matching row’s output as a deduplicated array.
| Pattern (Page Path) | Output (Pixel ID) |
|---|---|
.* | 123456789 (parent brand, always fires) |
/sports/.* | 234567890 (sports vertical pixel) |
/sports/football/.* | 345678901 (football regional pixel) |
/sports/football/match-report/ returns [“123456789”, “234567890”, “345678901”] — all three matching pixelsHandle RegEx exceptions with regexTableLookupCallback
Section titled “Handle RegEx exceptions with regexTableLookupCallback”regexTableLookupCallback separates the table from the fallback. The table handles documented patterns; the callback handles everything else.
| Pattern (Device) | Output |
|---|---|
iphone|ipad | ”ios” |
android | ”android” |
| Callback (no match) | Apply function |
{{Apply - secondary device-detection variable}} | |
Build chains of transformations with applyChain
Section titled “Build chains of transformations with applyChain”applyChain takes an ordered list of Apply functions and applies them sequentially in one variable.
| Step | Apply function |
|---|---|
| 1 | {{Apply - trim}} |
| 2 | {{Apply - toLowerCase}} |
| 3 | {{Apply - normalizeEmail}} |
| 4 | {{Apply - hashSHA256}} |
filterValue, identity, not — small primitives that compose
Section titled “filterValue, identity, not — small primitives that compose”identity returns its input unchanged. Useful as a no-op placeholder in chain configurations.
not inverts a boolean — same as Logic’s 🧩 NOT but as an Apply-mode chain primitive.
filterValue passes a value through if it satisfies a predicate, substitutes it with a fallback otherwise.
| Field | Value |
|---|---|
| Input | {{DL - revenue}} |
| Predicate | isValidNumber |
| If predicate false | {{zero}} |
defaultIfInvalid in Number, but works for any predicate from LogicGet the type or length of any value
Section titled “Get the type or length of any value”getType returns the JavaScript type of any input as a string — “string”, “number”, “boolean”, “object”, “array”, “undefined”, “null”.
getLength returns the length of an array, the length of a string, or the number of keys in an object. Useful for trigger conditions like “fire only if cart has more than 3 items.”
Composed patterns — chaining variables
Section titled “Composed patterns — chaining variables”Defensive name display with space separator
Build a full name with a space separator that GTM’s UI couldn’t otherwise express, and substitute “Anonymous” for any falsy result.
Multi-pixel routing for a CAPI tag
Get all applicable pixel IDs for an event, then iterate to fire one tag per pixel.
String-typed config to typed pipeline
Accept a string from a configuration field, cast to typed value, run downstream operations.
Why you don’t need Custom JavaScript
Section titled “Why you don’t need Custom JavaScript”The dominant Custom JavaScript pattern for the values in this category:
function() { return true; }
function() { return null; }
function() { return []; }
function() { return ” ”; }
function() { return {{DLV - revenue}} || 0; }Named templates replace the whole pattern:
- The intent is in the name.
spacemeans what it does.cjs - spacerequires opening the code. - They compose. Custom JavaScript can’t be Apply functions in chains. Value category variables are first-class chain primitives.
- Server-side portable. Named templates with explicit permissions transfer cleanly to sGTM.
- They don’t proliferate. One import replaces every container’s
cjs - true.
Cheatsheet
Section titled “Cheatsheet”| Goal | Variable | Mode |
|---|---|---|
| Inject literal boolean / null / number | true / false / null / NaN / zero | Direct |
| Inject single space (survives GTM stripping) | space | Direct |
| Inject empty string / array / object | emptyString / emptyArray / emptyObject / emptyObjectArray | Direct |
| Replace null only | nullTo | Direct / Apply |
| Replace undefined only | undefinedTo | Direct / Apply |
| Replace literal false only | falseTo | Direct / Apply |
| Replace any falsy value | falsyTo | Direct / Apply |
| Map truthy / falsy to custom outputs | mapTruthiness | Direct / Apply |
| Cast string to typed primitive | parseValue | Direct / Apply |
| Get all matching RegEx Table outputs | regexTableLookupAll | Direct |
| RegEx Table with separate fallback callback | regexTableLookupCallback | Direct |
| Apply ordered list of functions | applyChain | Direct / Apply |
| Pass-through (no-op) | identity | Apply |
| Invert a boolean (chainable) | not | Apply |
| Pass through if predicate true | filterValue | Direct / Apply |
| Get type of any value | getType | Direct / Apply |
| Get length of array / string / object keys | getLength | Direct / Apply |
How do I add a single space as a separator in a GTM variable?
GTM’s UI strips whitespace from configuration fields. Use the space variable, which returns a literal single space character.
How do I send a literal boolean true to a GTM tag?
Use the true variable, which returns the literal boolean true (not the string “true”). The typed constants fill the gap GTM’s UI leaves by always treating typed input as strings.
How do I replace null or undefined dataLayer values with a default?
Use nullTo, undefinedTo, or falsyTo depending on which input states should be substituted. All three accept a fallback that can be another variable, not just a constant.
How do I get all matching values from a RegEx Table?
GTM’s native RegEx Table returns the first matching row only. Use regexTableLookupAll to return every matching row’s output as an array.
How do I cast a string input to a typed value?
Use parseValue. It detects the intended type and returns the typed primitive. “42” becomes 42, “true” becomes true, “null” becomes null.
How does this differ from GTM’s native Format Value?
Format Value handles single substitutions per variable. The Value category’s substitution variables are chainable through Apply mode, support multiple substitutions in one pipeline, and compose with other operations from the framework.
Are these variables sandbox-safe in server-side GTM?
Yes. All templates run inside GTM’s sandboxed JavaScript environment using only permissioned APIs. They work in web and server containers.