Skip to content

String Variables

String Variables

CoreCategory51 Variables

Every string in your container arrives in the wrong shape for something. Emails need trimming, case folding, and gmail-specific normalization before hashing. Phone numbers need E.164 formatting. Order IDs need padding for sort-friendly analytics. Event parameters need truncation to fit platform limits. String is the text-hygiene layer — 51 sandbox-safe variable templates that handle these operations with names that carry intent. No Custom JavaScript. No RegEx Table gymnastics.

51 variables100% sandbox-safeWeb + ServerMIT licensed

Strings are everywhere in a GTM container — dataLayer values, URL paths, cookie contents, click attributes, form fields, scraped DOM content — and they almost never arrive in the shape the destination tag needs. Google Ads Enhanced Conversions requires emails trimmed, lowercased, gmail-dot-stripped, and plus-suffix-stripped before SHA-256 hashing. Meta CAPI requires phone numbers in E.164 format. GA4 truncates event parameters at 100 characters without warning. Merchant Center matching requires consistent casing on product IDs. Analytics reports depend on sort-friendly padded identifiers.

Every competing tutorial teaches these operations with Custom JavaScript. You end up with a container where half the variables are function() { return … } blocks whose purpose you can only discover by reading the code. The String category replaces them with named templates that carry their intent in their name. An audit becomes a scan, not an investigation.

The cross-cutting requirements that drive demand:

  • Privacy compliance. Every ad platform’s server-side API requires hashed PII, with platform-specific normalization rules that differ enough to trap the unwary.
  • Parameter hygiene. GA4, Meta CAPI, and Google Ads all have hard length limits that silently truncate your data unless you control it client-side.
  • Type coercion. Stringified JSON arrives in cookies and HTML attributes; you need objects, not strings.
  • Feed consistency. Merchant Center, Meta catalogs, TikTok catalogs fail silently when IDs don’t match the feed character-for-character.
  • Defensive normalization. Real dataLayers push strings with trailing spaces, inconsistent casing, HTML entities, and unpredictable encoding. One trim upstream prevents ten downstream failures.

Your strings probably come from one of these

Section titled “Your strings probably come from one of these”

The String variables don’t care where the text comes from. They operate on any value that resolves to a string. The four common sources, each with different quirks:

Source

dataLayer

Push-time strings from your backend. Can carry trailing whitespace, mixed casing, HTML entities, or stringified objects depending on the CMS.

Source

URL components

Path, query, hash. Predictable structure but needs parsing — second segment of path, value of utm_source, etc. URL-specific manipulation lives in the URL category.

Source

Click / form elements

Click Classes, Click Text, form field values, scraped DOM content. Often contain HTML tags, space-separated tokens, or encoded entities.

Source

Cookies / storage

Persistent identifiers, consent strings, stored user IDs, sometimes full stringified JSON objects. Usually URL-encoded; sometimes base64 or compound-delimited.

Whatever the source, the same variables apply. The recipes below cover the dominant use cases regardless of where your string starts.

Twenty-four variables, grouped by the job they do. Each links to its reference page with full config details. The Normalize group is the hero of the category — composed templates that encode documented platform rules so you don’t have to reimplement them.

Normalize email for Enhanced Conversions & Meta CAPI

Section titled “Normalize email for Enhanced Conversions & Meta CAPI”

Google Ads Enhanced Conversions, Campaign Manager 360, and Meta Conversions API all require email addresses to be normalized before SHA-256 hashing. The rules are published but scattered across several pages of Google’s documentation, and the Gmail-specific rules in particular are easy to miss — most Custom JavaScript implementations skip them.

Google’s documented normalization rules for email:

  1. Remove leading and trailing whitespace.
  2. Convert the entire address to lowercase.
  3. For gmail.com and googlemail.com only: remove all periods (.) from the local part (before the @).
  4. For gmail.com and googlemail.com only: remove the + sign and any characters that follow it, up to the @.
Source — Google Ads API

”Failing to do so will result in different hash values than Google expects for these domains, leading to missed matches.”

developers.google.com — Manage online click conversions

normalizeEmail applies all four rules in one pass. The output is ready to be hashed by GTM’s native APIs or passed directly to destinations that hash automatically.

Recipe — Normalize email for server-side APIs
Variable: normalizeEmail · Direct or Apply mode
FieldValue
Input{{DL - user_email}}
[email protected] becomes [email protected]

The silent-fail trap. Google accepts unnormalized hashed email addresses; it just won’t match them to accounts. You get no error, no warning — just a match rate that quietly underperforms. The same applies to Meta CAPI’s EMQ score. normalizeEmail prevents the whole class of failures with a variable whose name states its purpose.

E.164 is the international phone number format every ad platform’s server-side API requires: a leading +, a country code, then digits only — no spaces, dashes, or parentheses. Real-world inputs are endless variations: “(555) 123-4567”, “555.123.4567”, “+1 555 123 4567”, “15551234567” — all need to become “+15551234567”.

Source — Campaign Manager 360

”Format phone numbers according to the E164 standard. Include the plus sign (+) and the country code. For example, the US phone number (800)555-0200 should be formatted and normalized to +18005550200.”

developers.google.com — Enhanced Conversions
Recipe — Phone number to E.164
Variable: normalizePhone · Direct or Apply mode
FieldValue
Input{{DL - user_phone}}
Default country code1 (fallback when input has no explicit country code)
“(555) 123-4567” becomes “+15551234567”

When the input is already E.164-formatted, the variable passes it through unchanged — safe to apply defensively on every phone input regardless of source.

Meta’s quirk. Meta’s official CAPI documentation example shows phone numbers without the leading + (“16505551212” rather than “+16505551212”), while Google requires the +. normalizePhone has a toggle for this — default on for Google, off for Meta CAPI specifically.

Section titled “Parse a JSON string from a cookie or data attribute”

Stringified JSON arrives in more places than most analysts expect. Cookies with multi-field user state. HTML data-* attributes carrying structured payloads. Server-rendered <script type=“application/json”> blocks. Custom dataLayer pushes that stringify objects for browser-storage roundtrips. In every case, you need the parsed value — object, array, number — not the raw string.

Recipe — Parse a stringified cookie value into an object
Variable: parseJSON · Direct or Apply mode
FieldValue
Input{{Cookie - user_prefs}}
’{“id”:“u_123”,“tier”:“gold”}’ becomes {id: “u_123”, tier: “gold”}

Invalid JSON returns undefined rather than throwing, consistent with the library’s silent-skip pattern for malformed inputs. Chain a downstream Object-category variable (or feed directly into a tag that accepts objects) to use the parsed result.

GA4 silently truncates most event parameter values at 100 characters server-side. Custom dimension values face varying limits. Meta CAPI has parameter-specific caps. These truncations happen without warning — you see the data in Preview Mode, but what lands in the report is missing characters off the end, unpredictably.

Controlling the truncation client-side means you decide where the cut happens, and you can append an ellipsis or a marker to indicate the value was shortened.

Recipe — Truncate a long page title for GA4
Variable: truncate · Direct or Apply mode
FieldValue
Input{{Page Title}}
Max length100
Ellipsis (optional)
Respect word boundarytrue (avoid mid-word cuts)
predictable output, no silent server-side tail loss

Apply this defensively to any string parameter that might exceed a platform limit. GA4 event parameter names at 40 characters, event parameter values at 100, user property values at 36 — a truncate variable per destination saves entire classes of silent data loss.

Pad numeric IDs for sort-friendly analytics

Section titled “Pad numeric IDs for sort-friendly analytics”

Order IDs, step numbers, variant positions, section orderings — these are numeric identifiers that lexicographic sort engines treat as strings. Without padding, “10” sorts before “2”, and your funnel step “Step 2” appears after “Step 10” in GA4 reports. The fix is zero-padding: “01”, “02”, …, “10” all sort correctly as strings.

Recipe — Pad order step for sort-friendly reporting
Variable: padStart · Direct or Apply mode
FieldValue
Input{{DL - checkout_step}}
Target length2
Pad character0
“1” becomes “01”, “10” stays “10” — both sort correctly

The same pattern works for any short numeric ID where you want string-sort to match numeric-sort. Use padEnd for right-padding — less common in analytics contexts, useful for fixed-width formatting in compound IDs.

Scraping content from the DOM — innerHTML, element text, ARIA labels — frequently returns strings with embedded HTML tags and encoded entities. Sent to GA4 or Meta as-is, the tags pollute your reports and the entities break downstream matching. Two related operations, one per use case.

Recipe — Clean scraped DOM text for GA4
Variables: stripHtml (Apply) → decodeHtmlEntities (Direct)
FieldValue
Input (stripHtml){{Click Element - innerHTML}}
Chain outputInto decodeHtmlEntities
“<strong>Jane&#x27;s Sweater</strong>” becomes “Jane’s Sweater”

Scope. stripHtml removes tags to give you clean plain text. It is not an XSS sanitizer — do not use it for output that will be rendered back to users. For scraping-for-analytics purposes it’s exactly right; for security-critical contexts use a dedicated sanitizer library outside GTM.

Case conversion covers three common needs. Lowercase before hashing for Enhanced Conversions and Meta CAPI (already handled inside normalizeEmail). Uppercase for SKU matching when the Merchant Center feed uses uppercase IDs. Title case for display normalization in GA4 custom dimensions or downstream reports.

Recipe — Force SKU to uppercase for feed matching
Variable: toUpperCase · Direct or Apply mode
FieldValue
Input{{DL - product_sku}}
“sku-001” becomes “SKU-001”

Case conversion is the most Apply-chainable operation in the category. Pair with trim upstream for input cleanup, or padStart downstream for sort-friendly IDs.

Trailing spaces and newline characters are the most common dataLayer pollutant. They arrive silently from template engines that concatenate whitespace, from copy-paste in CMS fields, from poorly-normalized form inputs. They break exact-match comparisons, fail lookups, and produce duplicate rows in GA4 reports — “Apparel” and “Apparel ” count as two separate values.

Recipe — Defensive trim of any dataLayer value
Variable: trim · Direct or Apply mode
FieldValue
InputAny string (typically a dataLayer variable)
” Apparel\n” becomes “Apparel”

For values with interior whitespace issues too — multiple spaces between words, mixed tabs and spaces — chain collapseWhitespace after trim. trim handles the edges; collapseWhitespace handles the interior.

URL path segments, compound IDs, delimited tokens — extracting one piece of a larger string is one of the most common Custom JavaScript patterns in GTM containers. Two variables handle most cases without regex.

Recipe — Extract the category from /products/apparel/sku-001
Variables: substringAfter (Apply) → substringBefore (Direct)
FieldValue
Input (substringAfter){{Page Path}}
Delimiter/products/
Chain outputInto substringBefore with delimiter /
“apparel”

For index-based access, split with / and reference by array index is cleaner. For full URL parsing — extracting query parameters, manipulating paths, handling hash fragments — see the URL category.

Simple replacement — swap one substring for another — is replace. Pattern-based replacement with regex, capture groups, and partial reformatting is replaceRegex. Choice depends on whether the transformation is literal or pattern-based.

Recipe — Strip query parameters from a referrer URL
Variable: replaceRegex · Direct or Apply mode
FieldValue
Input{{Referrer}}
Pattern?.*$
Replacement"" (empty)

Capture groups work the same way they do in GTM’s native RegEx Table — $1, $2 reference the first and second captured groups. The difference is that replaceRegex is composable with the rest of the String category via Apply mode, while RegEx Table is a dead-end.

For URL-specific manipulation, use the URL category. Stripping tracking parameters by name, not pattern — removing fbclid, gclid, utm_* from a referrer — is handled more safely by paramOmit in the URL category, which parses the URL structure rather than pattern-matching on the raw string.

Slugification is the niche case that shows up in product recommendation engines, custom-built content hubs, and cross-platform link tracking. Turn “Men’s Merino Wool Sweater — Winter 2024” into “mens-merino-wool-sweater-winter-2024”. It’s a pipeline of lowercase, accent-strip, non-alphanumeric removal, and whitespace-to-dash — packaged as one template.

Recipe — Product name to URL slug
Variable: slugify · Direct or Apply mode
FieldValue
Input{{DL - item_name}}
“Men’s Merino Wool Sweater — Winter 2024” becomes “mens-merino-wool-sweater-winter-2024”

Doing this step-by-step with individual variables would need at least four chained operations. slugify packages the pipeline into one template, same way normalizeEmail does for the Enhanced Conversions rules. Both are examples of composed templates sold as primitives because the use case is so common and the rules so specific.

Outside the pre-built composed templates (normalizeEmail, slugify), the most valuable String patterns are three-to-five variable chains that transform an input into something a destination can actually use. Four worth memorizing:

Cookie JSON to usable object

Stringified cookie value parsed and ready to pass to a tag or downstream Object-category variable.

trimApplyparseJSONDirect

Feed-matching product ID

Bare dataLayer SKU to the Merchant Center-compatible composed ID. Padded and cased consistently so sort order matches numeric order.

trimApplytoUpperCaseApplypadStartDirect

Scraped DOM text to GA4-safe parameter

From raw innerHTML to a clean, truncated, length-limited value that won’t be silently cut server-side.

stripHtmlApplydecodeHtmlEntitiesApplytruncateDirect

Each chain is readable end-to-end from the variable list. The full semantic of the transformation lives in the variable names — no code comments required.

Every tutorial on PII hashing, email normalization, URL path extraction, SKU formatting, or JSON parsing eventually arrives at the same pattern:

function() {
var email = {{DLV - user_email}};
email = email.trim().toLowerCase();
var parts = email.split('@');
if (parts[1] === 'gmail.com' || parts[1] === 'googlemail.com') {
parts[0] = parts[0].replaceAll('.', '').split('+')[0];
}
return parts.join('@');
}

Then a second Custom JavaScript variable hashes the result. Then a third for the phone. Then a fourth to parse a cookie. Every piece of the logic lives only in the code; the variable name is usually something like cjs - em.

Named templates replace the whole pattern:

  • Intent carried in the name. normalizeEmail means exactly one thing. cjs - em means whatever the code inside happens to do today.
  • Rules encoded once. When Google updates the Enhanced Conversions normalization rules, you update one template. Every chain picks up the fix automatically. With Custom JavaScript, you track down every instance and fix it by hand.
  • Server-side portability. sGTM runs in a stricter sandbox than the web container. Many ad-hoc Custom JavaScript patterns from web don’t transfer. Named templates built for sandbox compatibility do.
  • Auditability. A container full of named templates is scannable from the variable list. A container full of Custom JavaScript is investigated, not read.
GoalVariableMode
Email for Enhanced ConversionsnormalizeEmailDirect / Apply
Phone number to E.164normalizePhoneDirect / Apply
URL slug from any textslugifyDirect / Apply
Parse stringified JSONparseJSONDirect / Apply
Truncate to max lengthtruncateDirect / Apply
Zero-pad a numeric IDpadStart / padEndDirect / Apply
Remove HTML tags from scraped textstripHtmlApply
Decode HTML entitiesdecodeHtmlEntitiesApply
Remove leading/trailing whitespacetrimDirect / Apply
Collapse interior whitespacecollapseWhitespaceApply
Remove diacritics (é → e)stripAccentsApply
Lowercase / uppercase / title casetoLowerCase / toUpperCase / toTitleCaseDirect / Apply
Extract before / after delimitersubstringBefore / substringAfterApply
Extract by index rangesubstringApply
Literal string replacementreplaceApply
Pattern-based replacementreplaceRegexApply
Split by delimiter into arraysplitApply
Join strings with optional separatorconcatDirect
Boolean containment testscontains / startsWith / endsWithDirect

How do I normalize email addresses for Google Ads Enhanced Conversions in GTM?

Google’s documented rules are: trim whitespace, lowercase, and for gmail.com/googlemail.com only, remove all periods from the local part and strip any +suffix. The normalizeEmail variable applies these rules in one pass.

How do I parse a JSON string into an object in GTM without Custom JavaScript?

parseJSON takes a string containing valid JSON and returns the parsed value. Common sources: cookie values that contain stringified objects, HTML data-* attributes, server-rendered script tags. Invalid JSON returns undefined rather than throwing.

How do I truncate strings to fit GA4 parameter limits?

GA4 silently truncates most event parameter values at 100 characters server-side. Use truncate with a target length to control the cut point client-side. Optionally append an ellipsis to indicate truncation happened.

How do I pad numeric IDs so they sort correctly in GA4 reports?

Lexicographic sort treats “10” as coming before “2”. Zero-pad with padStart: “01”, “02”, …, “10” all sort correctly as strings. Use a target length of 2 for step numbers up to 99, 3 for up to 999, etc.

How do I format phone numbers to E.164 for Meta CAPI and Google Ads?

normalizePhone strips all non-digit characters, applies a default country code when missing, and returns E.164 format. Google Ads requires the leading +; Meta CAPI’s documentation example omits it — normalizePhone has a toggle for this.

Are these variables sandbox-safe in server-side GTM?

Yes. Every template runs inside GTM’s sandboxed JavaScript environment using only permissioned APIs. Most are available in both web and server containers — normalizeEmail and normalizePhone in particular are designed for sGTM PII workflows.

How do I chain multiple String variables together?

Most String variables have an Apply mode that returns a reusable function rather than a final value. You chain these templates together by feeding that function into another variable’s Input Function field (to transform the string before processing) or into its Output Function field (to transform the result after processing). For example, using trim (Apply) in the Input Function of toLowerCase (Direct).