Skip to content

Array Variables

Array Variables

CoreCategory31 Variables

A user’s tags arrive as [“sports”, “premium”, “subscriber”]. A DOM scrape returns an array of element IDs. A backend pushes a list of consent purposes. GTM’s native trigger conditions don’t natively understand array containment — there’s no “fire when tags include any of these values” option. Array is the functional layer the rest of the framework runs on — 31 sandbox-safe variable templates for containment tests, array reshaping, slicing, and the higher-order functions (map, filter, reduce) that other categories’ Apply chains compose against.

31 variables100% sandbox-safeWeb + ServerMIT licensed

Arrays show up in three places in a GTM container, and GTM’s built-in tooling doesn’t handle any of them well:

  • Trigger conditions on array contents. Sites push dataLayer.user_tags = [“premium”, “subscriber”], then need to fire a tag when one of a list of values is present. GTM’s native contains operator matches the array’s stringified form — which breaks on partial matches and offers no AND/OR semantics across multiple values.
  • DOM scraping returns arrays. querySelectorAll and similar APIs return collections that need to be filtered, deduplicated, mapped, or counted before being sent to a tag.
  • Tag parameters expect array shapes. Some destinations want their input as an array — Meta CAPI’s user-data fields, custom GA4 parameters, server-side tag payloads. Building those arrays from individual variables is a Custom JavaScript pattern in every container.

Beyond the direct GTM use cases, the category serves a deeper architectural role: the higher-order functions are the mechanism that powers Apply chains across the framework. When the URL Transformer applies a function to query parameters, it’s iterating over an array with map. When Items filters by a property, it’s using filterArray. The Array category is the functional toolkit other categories compose against.

Three jobs: containment, reshaping, functional

Section titled “Three jobs: containment, reshaping, functional”
Containment tests

Fire tags based on array contents

includesAll, includesAny, includesNone — boolean tests for trigger conditions on array values. The clean answer to “fire when user has any of these tags.”

Reshape & slice

Make arrays the shape downstream needs

Construct, deduplicate, flatten, sort, slice. Take DOM-scraped or dataLayer arrays and produce the exact shape a tag’s parameter requires.

Functional toolkit

map, filter, reduce as named templates

The higher-order functions that JavaScript developers reach for daily. Available as composable, sandbox-safe variables that other categories’ Apply chains use under the hood.

Thirty-one variables, with the containment tests as the hero group.

The most direct GTM use case. A site pushes user attributes as an array — content tags, audience segments, consent purposes — and you need to fire a tag conditionally based on whether specific values are present.

GTM’s native contains operator on a Data Layer Variable matches the array’s stringified form. It fails on partial matches (a value of “sport” would also match [“sports”]), can’t express AND/OR semantics across multiple values, and doesn’t behave correctly when the dataLayer pushes a JavaScript array object.

Recipe — Fire when user has any of a list of premium tags
Variable: includesAny · Direct mode · Use as trigger condition
FieldValue
Array input{{DL - user_tags}}
Lookup values[“premium”, “vip”, “enterprise”, “founder”]
Returns true when the user’s tags include any of the listed values

The three containment variables cover the three semantic cases. includesAll for compound qualification. includesNone for blocklists. includesAny for the most common any-of-list matching.

Why this matters for consent. Consent management platforms typically push arrays of granted purposes — [“analytics”, “advertising”, “personalization”]. Firing a tag only when consent for “advertising” is granted is exactly an includesAny with [“advertising”] as the lookup.

Some tag destinations expect array-shaped parameters even when the source values are individual fields. The constructors handle the assembly job.

Recipe — Build a phone-number array for Meta CAPI
Variable: ⚡ ARRAY › From Values · Direct mode
SlotValue
Input 1{{Apply - normalizePhone on primary_phone}}
Input 2{{Apply - normalizePhone on secondary_phone}}
Input 3{{Apply - normalizePhone on work_phone}}
Array of E.164-formatted phone numbers, ready as user_data.ph on a CAPI tag

Arrays from outside the framework arrive in the wrong shape constantly. Four reshaping primitives cover the common needs.

Recipe — Clean a DOM-scraped array of product IDs
Variables: compact (Apply) → uniq (Direct)
FieldValue
Input[null, “sku-001”, “sku-002”, “sku-001”, "", “sku-003”]
After compact[“sku-001”, “sku-002”, “sku-001”, “sku-003”]
After uniq[“sku-001”, “sku-002”, “sku-003”]
Clean, deduplicated array ready as a tag parameter

Some arrays are too large to send wholesale. GA4 limits event parameters. Server-side tag payloads often have JSON size limits.

Recipe — Take only the first 10 items for a GA4 parameter
Variable: takeItems · Direct or Apply mode
FieldValue
Input array{{DL - search_results}} (could be 100+ items)
N10
First 10 items, ready as a GA4 event parameter
Recipe — Join an array of tags into a comma-separated string for GA4
Variable: join · Direct or Apply mode
FieldValue
Input array[“sports”, “premium”, “subscriber”]
Separator, (or {{space}}, or any delimiter)
“sports,premium,subscriber” — ready as a GA4 custom dimension value

every and some are boolean aggregations: every item satisfies a predicate, or at least one does. Use as trigger conditions when you need “fire only if every item in the cart is discount-applicable” or “fire if any item triggered a stockout warning.”

  • find returns the first item matching a predicate.
  • indexOf returns the index of a value’s first occurrence, or -1.
  • lastIndexOf for the last occurrence.
  • findIndexByCallback and findIndexByRegex for index-based search by predicate or pattern.
Recipe — Find the index of the first sale item in cart
Variable: findIndexByCallback · Direct or Apply mode
FieldValue
Input array{{DL - ecommerce.items}}
Predicate{{Apply - itemHasProperty discount > 0}}
Index of the first discounted item, or -1

JavaScript developers reach for map, filter, and reduce daily. The Array category provides them as named templates that take an Apply-mode function as their callback.

Recipe — Map an array of prices to formatted display strings
Variable: map · Direct mode
FieldValue
Input array[12.5, 49.99, 199]
Apply function{{Apply - formatNumber EUR}}
[“12,50 €”, “49,99 €”, “199,00 €“]

Clean DOM-scraped IDs

Take a noisy DOM-scraped array, strip falsy values, deduplicate, take the first 10.

compactApplyuniqApplytakeItemsDirect

Build and join

Construct an array from individual variables, then join into a single string for a GA4 parameter.

⚡ ARRAY › From ValuesApplycompactApplyjoinDirect

Audience qualification

Test multiple containment conditions to qualify a user for an audience segment.

includesAllDirect·[required tags]+includesNoneDirect·[excluded tags]

The dominant Custom JavaScript pattern for array operations in GTM:

function() {
var tags = {{DLV - user_tags}};
if (!Array.isArray(tags)) return false;
var lookup = [‘premium’, ‘vip’, ‘enterprise’];
return tags.some(function(tag) {
return lookup.indexOf(tag) !== -1;
});
}

Half a dozen lines that boil down to includesAny(tags, lookup). Each one:

  • Buries intent in code. The lookup list is hardcoded inside the function.
  • Doesn’t compose. AND and OR semantics across two arrays means two functions.
  • Lacks defensive type handling. Half the implementations skip Array.isArray.
  • Doesn’t transfer to sGTM. Named templates with explicit permissions transfer cleanly.
GoalVariableMode
Trigger when array contains any of a listincludesAnyDirect
Trigger when array contains all of a listincludesAllDirect
Trigger when array contains none of a listincludesNoneDirect
Build an array from individual variables⚡ ARRAY › From ValuesDirect / Apply
Build an array with explicit positions⚡ ARRAY › From Indexed ValuesDirect / Apply
Wrap a value in a length-1 arraywrapInArrayDirect / Apply
Transform every itemmapDirect / Apply
Keep items matching a predicatefilterArrayDirect / Apply
Collapse to a single valuereduce / reduceRightDirect / Apply
Boolean: every item passes / any item passesevery / someDirect
Find first item matching predicatefindDirect / Apply
First / last / all-but-first itemhead / last / tailDirect / Apply
First N / last N itemstakeItems / takeItemsRightDirect / Apply
Skip first N / last N itemsdropItems / dropItemsRightDirect / Apply
Split into chunks of size NchunkDirect / Apply
Item at specific indexselectFromArrayDirect / Apply
Index of value (first / last)indexOf / lastIndexOfDirect
Index of item matching predicate / regexfindIndexByCallback / findIndexByRegexDirect / Apply
Remove duplicate valuesuniqDirect / Apply
Remove falsy valuescompactDirect / Apply
Flatten one level of nestingflattenDirect / Apply
Reverse orderreverseDirect / Apply
Sort with comparatorsortDirect / Apply
Concatenate items into a stringjoinDirect / Apply

How do I fire a GTM tag when a dataLayer array contains specific values?

Use includesAny to fire when at least one of a list is present, includesAll when every value must be present, or includesNone when none should be present. Each returns a boolean for use as a trigger condition.

Why doesn’t GTM’s native “contains” work for arrays?

GTM’s contains operator on a Data Layer Variable matches the array’s stringified form. That works in some cases but breaks on partial matches (“sport” matches [“sports”]) and offers no AND/OR semantics across multiple lookup values.

How do I build an array from individual values to send to a tag?

Use ⚡ ARRAY › From Values to assemble an array from individual variable inputs. It takes N slots, each pointing to a variable, and returns an array of those values.

How do I deduplicate an array in GTM?

Use uniq to return only unique values. Pair with compact to also remove falsy values like null, undefined, and empty strings.

How do I get the first or last item of an array?

Use head for the first item, last for the last item, tail for everything except the first. For specific indices, use selectFromArray. For taking N items from either end, use takeItems and takeItemsRight.

How do I run map, filter, or reduce on an array?

The map, filterArray, and reduce variables accept an Apply-mode function as their callback. Same semantics as JavaScript’s Array methods, but as composable named templates.

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 both web and server containers.