A lot of ecommerce setups don't live on one clean domain. Ads point at a campaign or intermediary domain, a redirect sends the visitor to the main store, and checkout happens somewhere else again. Every hop is a chance for Google Analytics 4 to lose the visitor and start a brand new session.
The symptoms are familiar: your own domain shows up as a top referrer, paid traffic looks like it never converts, and "Direct" or "(not set)" quietly swallows revenue. Google Ads and Meta still report conversions, but GA4 can't tell you which campaign drove them.
This post walks through how we set up and verify cross-domain tracking for that kind of flow. It's aimed at developers and marketers who can edit tags and redirects, and who want a checklist they can run end to end rather than a list of settings.
Why GA4 loses the visitor
GA4 identifies a browser with a first-party cookie (_ga) set on the domain the visitor is on. Cookies don't travel between brand-campaign.com and brand.com, so when the visitor crosses over, the second domain sees a stranger. It creates a new client ID and a new session, and the referrer is the first domain.
Cross-domain measurement fixes this by passing the client and session identifiers along in a URL parameter called _gl when the visitor clicks a link to another configured domain. The receiving page reads _gl, adopts the same IDs, and the session carries on.
That only works if three things are true:
- Both domains run the same GA4 property (the same measurement ID).
- Both domains are listed in the property's cross-domain configuration.
- The
_glparameter survives the trip, including through any redirects.
Most broken setups fail on the third point.
Step 1: One property, one tag, every domain
Check that every domain in the journey sends data to the same GA4 web data stream. If the intermediary domain has its own property, the visitor's history starts over the moment they leave it, no matter what else you configure.
Use the same Google tag (or the same Google Tag Manager container) on every domain. Two different tags with the same measurement ID can work, but it makes debugging much harder later.
Step 2: Configure your domains in GA4
In GA4, go to Admin, then Data streams, pick your web stream, open "Configure tag settings", then "Configure your domains". Add each domain in the journey, for example:
brand-campaign.combrand.com- any separate checkout or booking domain you control
Use "Contains" or "Exactly matches" rules that cover the subdomains you actually use. Once this is saved, the Google tag starts decorating outbound links to those domains with _gl automatically.
Step 3: Add unwanted referrals
In the same tag settings, open "List unwanted referrals" and add your own domains and any payment provider that bounces visitors back to the site (PayPal, Klarna, 3-D Secure pages). Without this, a return from the payment page can start a new session credited to the payment provider instead of your campaign.
Step 4: Make sure redirects keep the query string
This is where intermediary-domain setups usually break. Automatic link decoration only adds _gl to links the visitor clicks. If your intermediary page uses a server-side redirect, a meta refresh or a JavaScript location change, the tag never decorates anything, and even a decorated URL can lose its parameters on the way.
Two rules cover most cases:
Preserve the full query string on every redirect. A 301 or 302 from the intermediary domain must pass gclid, fbclid, utm_* and _gl through untouched. In nginx that looks like:
location / {
return 301 https://brand.com$request_uri;
}
$request_uri includes the query string. A rule like return 301 https://brand.com/; silently drops it.
Don't rely on script redirects to carry _gl. The Google tag decorates links when a visitor clicks them. A window.location change or meta refresh on page load happens before or outside that, so no _gl is added and the session breaks. If the intermediary page has to send people on, give it a real link or button to the main domain that the visitor clicks, and let the tag decorate it. If you're using Google Tag Manager, you can also decorate forms with the linker settings in the Google tag configuration.
The cleanest option of all is to avoid the extra hop when you can. If the intermediary exists for ad policy reasons, keep a real landing page there with a clear call to action, rather than an instant redirect. You get decoration for free and a page that reviewers can actually see.
Step 5: Keep ad click IDs alive
Cross-domain linking keeps the GA4 session together, but Google Ads and Meta also rely on their own click IDs. Make sure gclid reaches the domain where your conversion tag fires, and enable the Conversion Linker in Google Tag Manager on every domain. For Meta, pass fbclid through so the _fbc cookie can be set on the converting domain, and send purchases through the Conversions API where you can.
If the store is on Shopify, its native Google and Meta channels handle the checkout side. Your job is to get the visitor and their parameters onto the store domain intact.
Step 6: Verify end to end
Don't trust the settings screen. Walk the journey yourself:
- Open an ad-style URL on the first domain with test parameters, for example
?utm_source=test&utm_medium=cpc&gclid=TEST123. - Follow the path to the main domain and check the address bar. You should see
_gl=alongside your original parameters. - In GA4 DebugView (with Tag Assistant connected), confirm the
page_viewon the second domain has the same session, not a newsession_startwith a referral. - Complete a test purchase or lead form and check the conversion is attributed to your test source.
A day or two later, check the reports. In Traffic acquisition, your own domains should disappear as referrers, and the share of "Direct" conversions should drop.
Common mistakes
- Different measurement IDs on each domain. Linking can't merge two properties.
- Redirects that drop parameters. The most common cause by far.
-
Caching layers stripping
_gl. Some CDN or page-cache rules ignore or remove unknown query parameters. Allow_glthrough. - Consent banners blocking the linker. If analytics consent is denied on the first domain, there's nothing to pass on. Make sure consent choices carry across domains too.
- Forgetting payment returns. Add payment providers to unwanted referrals.
Wrapping up
Cross-domain tracking is one setting in GA4, but making it work is a journey problem, not a settings problem. Use one property, list every domain, keep the query string through every hop, and test the full path with real parameters. Once the session survives the handoff, your campaign data finally lines up with what the ad platforms report.
We work through setups like this with ecommerce brands at Web Consulting Agency. If your paid traffic looks like it never converts in GA4, the handoff between domains is the first place to look.
Top comments (0)