URL Variables
URL Variables
URLs leak data and break attribution. Tracking parameters fragment your reports. Referrers carry session IDs and PII into GA4. Self-referrals from payment redirects shatter campaign attribution. Safari now strips click IDs entirely. Single-page apps push hash fragments that GA4 silently discards. URL is the canonicalization layer — 28 sandbox-safe variable templates that strip, reshape, and reconstruct URLs for clean tracking. No Custom JavaScript.
Why this category exists
Section titled “Why this category exists”Every container handles URLs constantly — page URLs, referrers, click URLs, redirect URLs, server-side incoming URLs. None of them arrive in the shape your tags actually need. Tracking parameters from Facebook, Google, Microsoft, TikTok, and Mailchimp clutter every report. Payment-redirect referrers contain session IDs that GA4 logs as PII. Single-page applications push hash fragments that GA4 silently discards. Different parts of your stack speak different URL conventions.
The URL category solves four cross-cutting problems:
- Tracking-parameter pollution.
fbclid,gclid,_gl,msclkid,wbraid,gbraid, and dozens of others fragment your GA4 page reports because every value creates a unique URL row. Stripping them before tag firing is the only clean fix. - Referrer hygiene. Payment providers, OAuth flows, and embedded iframes frequently pass session IDs and tokens in the referrer URL. Sending these to GA4 unmodified leaks PII into your reports and creates self-referrals that break attribution.
- SPA virtual pageviews. Single-page applications change the hash fragment without reloading. GA4 strips fragments from
page_locationby default — virtual pageviews vanish unless you explicitly construct the URL with the fragment included. - URL canonicalization. Multi-domain tracking, AMP-to-canonical mapping, relative-to-absolute conversion. The container ends up acting as the URL adapter between systems that all spell the same address differently.
All four problems share the same architecture: parse the URL, modify components, reconstruct. The ⚡ URL › Transformer handles the full lifecycle in one variable.
URL anatomy and what each variable extracts
Section titled “URL anatomy and what each variable extracts”The variables in this category map cleanly to the standard parts of a URL. Understanding the anatomy makes the variable list self-organizing.
Each component has a dedicated extraction variable, plus tests, encoders, and the URL › Transformer that operates on the whole URL as a structured value.
The variables — at a glance
Section titled “The variables — at a glance”Twenty-eight variables, grouped by the job they do. The Transformation group is the hero — the URL › Transformer applies modification functions to query and hash parameters in a single pass.
https:, http:, etc.extractHostHostname plus port if non-default.extractHostnameDomain only — example.com.extractOriginProtocol + host — https://example.com.extractPathnamePath portion — /products/apparel.extractPortPort number when non-default.extractSegmentByIndexA specific segment from a pathname by index.extractUserNameUsername from https://user:pass@host.Strip tracking parameters from a URL
Section titled “Strip tracking parameters from a URL”Every link clicked from Facebook adds fbclid. Every Google Ads click adds gclid (or wbraid/gbraid in iOS). Microsoft Ads adds msclkid. Mailchimp adds mc_cid and mc_eid. Cross-domain Google Analytics linkers add _gl. Each parameter is a unique value per click, so each click creates a unique URL — and every unique URL becomes a separate row in your GA4 page report. One real page can fragment into thousands of URL rows in your reports.
The standard tracking parameters worth stripping before they reach your tags:
| Field | Value |
|---|---|
| Input URL | {{Page URL}} |
| Query Apply | {{Apply - omitParamsFromString [fbclid, gclid, gclsrc, _gl, msclkid, wbraid, gbraid, ttclid, mc_cid, mc_eid]}} |
| Hash Apply | (none) |
page_location parameter on every GA4 tagSet this on the GA4 page_location parameter — overriding GA4’s default — and your page reports collapse from thousands of unique URLs back to the canonical set.
What about GA4’s “Exclude URL Query Parameters” setting? GA4’s built-in setting strips parameters from page_location after collection. The Transformer approach strips them before collection, which means clean values flow through to all your tags simultaneously — Meta CAPI, Google Ads, TikTok, server-side GTM, BigQuery export. GA4’s setting only affects GA4.
Capture click IDs before Safari removes them
Section titled “Capture click IDs before Safari removes them”Apple’s recent privacy updates strip click IDs (gclid, fbclid, msclkid) from URLs in Safari for users who arrived from cross-site tracking contexts. By the time your GTM container reads the URL, the click ID may already be gone — but Google Ads, Meta CAPI, and Microsoft Ads all need it for offline conversion attribution.
The defense is to capture click IDs into first-party storage on the first pageview, then read from storage on subsequent events.
| Field | Value |
|---|---|
| Input | {{Page URL}} |
| Reference | gclid (or any click ID) |
| Storage | First-party cookie with 90-day expiry |
{{Cookie - stored_gclid}} for the conversion tagClean referrer URLs of PII before sending to GA4
Section titled “Clean referrer URLs of PII before sending to GA4”Referrer URLs frequently carry session tokens, user IDs, and PII parameters that you don’t want to send to GA4. Payment redirects from Stripe and PayPal include session IDs. OAuth callbacks include access tokens. Sending these unmodified to GA4 is a GDPR concern and a violation of GA4’s terms of service.
| Field | Value |
|---|---|
| Input URL | {{Referrer}} |
| Query Apply | {{Apply - omitParamsFromString [session_id, token, access_token, user_id, email, fbclid, gclid]}} |
page_referrer parameter on GA4 eventsKeep only canonical UTM parameters
Section titled “Keep only canonical UTM parameters”Some workflows need the inverse of stripping — keeping only a known set of parameters and discarding everything else. Building a canonical URL for content grouping, generating a clean share-link, or producing a deduplicated page_location.
| Field | Value |
|---|---|
| Input URL | {{Page URL}} |
| Query Apply | {{Apply - pickParamsFromString [utm_source, utm_medium, utm_campaign, utm_term, utm_content, utm_id]}} |
Track SPA navigation with hash fragments
Section titled “Track SPA navigation with hash fragments”Single-page applications change the URL hash fragment (#products/sku-001) to represent navigation without reloading the page. GA4’s default behavior strips the fragment from page_location — virtual pageviews vanish unless you explicitly construct the URL with the fragment included.
”In Google Analytics, fragment changes are not tracked by default, and the URL paths that are passed to GA with your Pageview hits are stripped of these fragments.”
| Field | Value |
|---|---|
| Input URL | {{Page URL}} |
| Concat order | {{extractPathname}} + {{extractSearch}} + {{extractHash}} |
/app + ?ref=email + #products/123 = “/app?ref=email#products/123”Extract custom UTM parameters for GA4 custom dimensions
Section titled “Extract custom UTM parameters for GA4 custom dimensions”GA4 captures the standard UTM parameters automatically. Custom UTM parameters your team invents — utm_audience, utm_creative_format, utm_placement — don’t show up in standard reports until you extract them and map them to custom dimensions.
| Field | Value |
|---|---|
| Input URL | {{Page URL}} |
| Reference | utm_audience |
utm_audience, ready as a custom event parameterExtract URL components — host, hostname, origin
Section titled “Extract URL components — host, hostname, origin”Three closely related variables get confused constantly because they sound similar:
extractHostnamereturns the domain only —example.com. This is what you want for most “is this a same-domain link” checks.extractHostreturns hostname plus port if non-default —example.com:8080. Use this when port matters.extractOriginreturns protocol plus host —https://example.com. Use it for security-related comparisons.
| Field | Value |
|---|---|
| Click hostname | {{Apply - extractHostname on Click URL}} |
| Page hostname | {{Apply - extractHostname on Page URL}} |
| Trigger condition | Click hostname does not equal Page hostname |
Encode and decode URL components
Section titled “Encode and decode URL components”Two pairs of encoding variables exist because URLs have two different encoding contexts. Confusing them is a common bug source.
encodeUri/decodeUri— for entire URIs. Preserves reserved characters like:,/,?,#.encodeURIComponent/decodeUriComponent— for individual components. Encodes everything. Use when injecting a value into a URL parameter.
The rule of thumb: if you’re building a URL parameter value, use encodeURIComponent. If you’re transmitting a complete URL through another medium, use encodeUri.
Composed patterns — chaining variables
Section titled “Composed patterns — chaining variables”Four canonical chains for the most common URL-modification pipelines:
Clean page URL for GA4 page_location
Strip every known tracking parameter in one Transformer call.
Clean referrer for GA4 page_referrer
Strip session IDs and PII from the referrer URL.
SPA page_location with hash fragment
Build the full URL including the hash fragment that GA4 strips by default.
Outbound link with UTM injection
Add campaign UTMs to a link click before sending to a destination.
Why you don’t need Custom JavaScript
Section titled “Why you don’t need Custom JavaScript”The dominant Custom JavaScript pattern for URL manipulation in GTM:
function() {
var url = {{Page URL}};
var paramsToStrip = [‘fbclid’, ‘gclid’, ‘_gl’, ‘msclkid’];
var u = new URL(url);
paramsToStrip.forEach(function(p) {
u.searchParams.delete(p);
});
return u.toString();
}The URL › Transformer with omitParamsFromString does the same job:
- Configurable, not coded. Adding a new tracking parameter means editing a list, not the code.
- Self-documenting. The variable name says what it does.
- Sandbox-safe. Works in both web and server containers.
- Composable. The same Transformer accepts different Apply functions for different jobs — strip for cleaning, pick for canonicalization, assign for injection.
Cheatsheet
Section titled “Cheatsheet”| Goal | Variable | Mode |
|---|---|---|
| Strip tracking params (fbclid, gclid, etc.) | ⚡ URL > Transformer + omitParamsFromString | Direct |
| Keep only specific params (e.g. UTMs) | ⚡ URL > Transformer + pickParamsFromString | Direct |
| Add or update params | ⚡ URL > Transformer + assignParamsToString | Direct |
| Get protocol / host / hostname / origin | extractProtocol / extractHost / extractHostname / extractOrigin | Direct / Apply |
| Get raw search or parsed search params | extractSearch / extractSearchParams | Direct / Apply |
| Get raw hash or parsed hash params | extractHash / extractHashParams | Direct / Apply |
| Test for query string / fragment / specific value | hasQueryString / hasFragment / hasParameterWithValue | Direct |
| Encode a full URI / single component | encodeUri / encodeURIComponent | Apply |
| Convert relative URL to absolute | completeUrl | Direct / Apply |
| Get all URL parts as one object | parseUrlComponents | Direct / Apply |
| Build URL from a parts object | buildUrlFromParts | Direct |
How do I strip fbclid and gclid from URLs in GTM?
Use the URL > Transformer with omitParamsFromString as the query Apply function. List the parameters to remove and the variable returns the URL with those parameters stripped. Use the result as page_location on your GA4 tag.
Can I capture click IDs before Safari removes them from URLs?
Yes. Capture fbclid, gclid, msclkid, wbraid, gbraid into a first-party cookie on initial pageview using extractSearchParams, before Safari’s URL cleaning takes effect. On subsequent events, read from the cookie rather than the URL.
How do I clean referrer URLs of PII before sending to GA4?
Apply the URL > Transformer to the referrer URL with omitParamsFromString as the query Apply function. List session IDs, user tokens, and any PII parameters. Use the cleaned referrer as page_referrer on GA4 events.
How do I track hash fragment changes in a single-page application?
Use extractHash or extractHashParams on the History Change event. Concatenate the fragment to the page path, and pass the result as page_location on the GA4 page_view event.
What is the difference between extractHost and extractHostname?
extractHostname returns the domain only — example.com. extractHost returns the domain plus port if non-default — example.com:8080. For most GA4 use cases, extractHostname is what you want.
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. The Transformer is particularly valuable in sGTM where you reshape incoming URLs before forwarding to destinations.