String Variables
String 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.
On this page
- Why this category exists
- Your strings probably come from one of these
- The variables — at a glance
- Normalize email for Enhanced Conversions & Meta CAPI
- Format phone numbers to E.164
- Parse a JSON string from a cookie or data attribute
- Truncate strings for GA4 parameter limits
- Pad numeric IDs for sort-friendly analytics
- Strip HTML from scraped content
- Convert case for feed matching
- Trim and collapse whitespace
- Extract a segment between delimiters
- Replace literal or pattern
- Generate a URL slug
- Composed patterns — chaining variables
- Why you don’t need Custom JavaScript
- Cheatsheet
- FAQ
Why this category exists
Section titled “Why this category exists”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:
dataLayer
Push-time strings from your backend. Can carry trailing whitespace, mixed casing, HTML entities, or stringified objects depending on the CMS.
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.
Click / form elements
Click Classes, Click Text, form field values, scraped DOM content. Often contain HTML tags, space-separated tokens, or encoded entities.
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.
The variables — at a glance
Section titled “The variables — at a glance”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.
1 into 01.padEndRight-pad to a target length.truncateCut a string to a maximum length with optional ellipsis.concatJoins multiple strings with an optional separator.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:
- Remove leading and trailing whitespace.
- Convert the entire address to lowercase.
- For
gmail.comandgooglemail.comonly: remove all periods (.) from the local part (before the@). - For
gmail.comandgooglemail.comonly: remove the+sign and any characters that follow it, up to the@.
”Failing to do so will result in different hash values than Google expects for these domains, leading to missed matches.”
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.
| Field | Value |
|---|---|
| Input | {{DL - user_email}} |
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.
Format phone numbers to E.164
Section titled “Format phone numbers to E.164”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”.
”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.”
| Field | Value |
|---|---|
| Input | {{DL - user_phone}} |
| Default country code | 1 (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.
Parse a JSON string from a cookie or data attribute
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.
| Field | Value |
|---|---|
| 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.
Truncate strings for GA4 parameter limits
Section titled “Truncate strings for GA4 parameter limits”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.
| Field | Value |
|---|---|
| Input | {{Page Title}} |
| Max length | 100 |
| Ellipsis (optional) | … |
| Respect word boundary | true (avoid mid-word cuts) |
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.
| Field | Value |
|---|---|
| Input | {{DL - checkout_step}} |
| Target length | 2 |
| Pad character | 0 |
“1” becomes “01”, “10” stays “10” — both sort correctlyThe 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.
Strip HTML from scraped content
Section titled “Strip HTML from scraped content”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.
| Field | Value |
|---|---|
| Input (stripHtml) | {{Click Element - innerHTML}} |
| Chain output | Into decodeHtmlEntities |
“<strong>Jane'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.
Convert case for feed matching
Section titled “Convert case for feed matching”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.
| Field | Value |
|---|---|
| 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.
Trim and collapse whitespace
Section titled “Trim and collapse whitespace”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.
| Field | Value |
|---|---|
| Input | Any 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.
Extract a segment between delimiters
Section titled “Extract a segment between delimiters”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.
| Field | Value |
|---|---|
| Input (substringAfter) | {{Page Path}} |
| Delimiter | /products/ |
| Chain output | Into 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.
Replace literal or pattern
Section titled “Replace literal or pattern”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.
| Field | Value |
|---|---|
| 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.
Generate a URL slug
Section titled “Generate a URL slug”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.
| Field | Value |
|---|---|
| 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.
Composed patterns — chaining variables
Section titled “Composed patterns — chaining variables”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.
Feed-matching product ID
Bare dataLayer SKU to the Merchant Center-compatible composed ID. Padded and cased consistently so sort order matches numeric order.
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.
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.
Why you don’t need Custom JavaScript
Section titled “Why you don’t need Custom JavaScript”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.
normalizeEmailmeans exactly one thing.cjs - emmeans 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.
Cheatsheet
Section titled “Cheatsheet”| Goal | Variable | Mode |
|---|---|---|
| Email for Enhanced Conversions | normalizeEmail | Direct / Apply |
| Phone number to E.164 | normalizePhone | Direct / Apply |
| URL slug from any text | slugify | Direct / Apply |
| Parse stringified JSON | parseJSON | Direct / Apply |
| Truncate to max length | truncate | Direct / Apply |
| Zero-pad a numeric ID | padStart / padEnd | Direct / Apply |
| Remove HTML tags from scraped text | stripHtml | Apply |
| Decode HTML entities | decodeHtmlEntities | Apply |
| Remove leading/trailing whitespace | trim | Direct / Apply |
| Collapse interior whitespace | collapseWhitespace | Apply |
| Remove diacritics (é → e) | stripAccents | Apply |
| Lowercase / uppercase / title case | toLowerCase / toUpperCase / toTitleCase | Direct / Apply |
| Extract before / after delimiter | substringBefore / substringAfter | Apply |
| Extract by index range | substring | Apply |
| Literal string replacement | replace | Apply |
| Pattern-based replacement | replaceRegex | Apply |
| Split by delimiter into array | split | Apply |
| Join strings with optional separator | concat | Direct |
| Boolean containment tests | contains / startsWith / endsWith | Direct |
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).