GA4 cross domain tracking exists to solve one specific problem: a visitor moves from one domain you own to another, and without configuration GA4 treats that as two people, two sessions, and a self-referral that destroys your attribution. Fixing it takes about five minutes in the interface. Verifying it takes longer, and skipping the verification is why so many setups look configured and are not.
Unlike Universal Analytics, GA4 handles the linker automatically once you list your domains. There is no separate allowlist snippet, no autoLink array, no cookie domain to set.
When you actually need it
You need cross-domain measurement when a single user journey spans more than one registrable domain and you want it recorded as one session. Typical cases:
- A marketing site on
example.comwith an app or store onexampleapp.com - A booking, ticketing or scheduling flow on a third-party domain such as a Calendly or Shopify-hosted checkout
- A hosted payment page that returns the visitor to your thank-you page
- A separate careers, docs or community domain that feeds conversions
You do not need it for subdomains. GA4 tracks blog.example.com and www.example.com as one property with no configuration, because the cookie is set at the registrable domain level. People configure subdomains as cross-domain out of caution and it causes no harm, but it solves nothing.
You also cannot use it on a domain where you cannot place your own Google tag. Cross-domain measurement requires the same measurement ID on both ends. If the third party will not host your tag, the technique does not apply — you are limited to unwanted-referral exclusion, which is a different setting with a different effect.
What breaks without it shows up in three common symptoms. Your own domain appears as a referral source in acquisition reports — the classic self-referral. Conversions get credited to that referral rather than to the campaign or organic search that genuinely earned them. And user counts inflate, because the same person is counted once per domain.
On an ecommerce site with an off-domain payment step, this pattern alone can make paid and organic look 30-40% less effective than they are, with the missing credit sitting under a referral row named after your own payment processor.
Setting up cross domain tracking in GA4
The configuration lives in the data stream, not at property level:
- Admin → Data streams → select your web stream.
- Under Google tag, open Configure tag settings.
- Choose Configure your domains.
- Add a condition for each domain. The match types are Contains, Begins with, Ends with, Equals, Matches regex and Starts with. Use Contains with the bare domain —
example.com— rather than a full URL with protocol. - Include every domain in the journey, including the one you are configuring from. Leaving out the origin domain is a frequent mistake.
- Save.
Then make sure the same Google tag with the same G- measurement ID is installed on all listed domains. Cross-domain measurement is a two-sided arrangement; listing a domain you have no tag on achieves nothing.
Be careful with Contains matching. Listing shop as a Contains condition will match shopify.com, shoppingcart.net and anything else containing the string, which appends linker parameters to destinations you never intended. Use the fullest safe string.
How the _gl parameter works
Once configured, GA4 appends a _gl parameter to links pointing at your listed domains. It carries the client ID and session information in an encoded form so the destination domain can continue the same session and user rather than minting new ones.
Two consequences follow. First, the parameter is short-lived by design — it is valid for a couple of minutes, so a link copied out of the address bar and pasted into a chat message does not permanently merge two people’s data. Second, it only decorates links the tag can see in the DOM at click time. Links generated by JavaScript after the tag has run, links inside iframes, and redirects executed server-side will often lose the parameter.
Server-side redirects are the biggest practical trap. If a click hits example.com/go which 302s to exampleapp.com, the linker parameter is usually stripped in the process. If your journey depends on such a hop, pass the parameter through the redirect explicitly or restructure the link.
Testing it, because configured is not the same as working
Run this test manually rather than assuming:
- Open your origin domain in a fresh browser profile with no ad blocker.
- Click a link through to the second domain.
- Look at the address bar on arrival. You should see a
_gl=parameter appended. - Open GA4’s DebugView with debug mode active and repeat the journey. You should see events from both domains under a single debug stream, with one
session_startat the beginning and none at the crossover. - Check Realtime for a single active user, not two.
A second session_start when you cross domains means the linker did not carry. Common causes: the destination lacks the tag, the domain condition does not match, an ad blocker is stripping the request, or the crossover goes through a server-side redirect.
After 24 to 48 hours — standard reports do not process faster — check acquisition reports for self-referrals. Your own domains should have disappeared from the referral list.
Unwanted referrals: the related setting people confuse it with
In the same tag settings panel sits “List unwanted referrals”. It tells GA4 to ignore a referrer entirely, so an inbound visit from that domain does not start a new attributed session and instead retains the previous source.
These are different tools. Cross-domain measurement stitches sessions across domains you tag. Unwanted referrals suppress a referral you cannot tag — most often a payment gateway that will not host your Google tag. If you can tag both domains, use cross-domain measurement. If you cannot, exclude the referral. Doing both for a fully tagged domain is redundant.
Reading the results honestly
Even a correct setup does not produce perfect stitching. Ad blockers, Safari’s storage policies, consent refusals and privacy extensions all break some share of the chain. Expect a residual band of unstitched journeys, and expect it to be larger on consumer sites than B2B.
Two other GA4 behaviours will show up while you investigate. Data thresholding withholds rows when Google Signals is on and the audience is small, which can make a cross-domain segment look empty when it is merely suppressed. And GA4’s attribution defaults to data-driven, with changes applying retroactively to historical reports — so if channel credit shifts after your fix, some of that is the fix and some may be a model setting somebody changed.
Where this sits in a wider measurement picture
Cross-domain measurement gets your on-site journey right. It tells you nothing about the search results that started it — the query, the impressions, the position you held on the day. Organic Search remains a channel bucket in GA4, and Search Console holds the rest.
SEO Rocket connects Google Search Console and GA4 and treats them as ground truth for your own site’s performance, showing real clicks and sessions beside third-party index estimates with each source clearly labelled, so you can read a session or conversion change against actual position movement rather than modelled numbers. It does not replace GA4, build custom GA4 reports, or configure cross-domain tracking on your behalf — that work happens in your data stream settings, and it is worth doing carefully once.
The short checklist
List every domain in the journey, including the origin. Confirm the same measurement ID is deployed on all of them. Use match conditions specific enough not to catch unrelated domains. Walk the journey yourself and look for _gl in the URL and a single session_start in DebugView. Then wait two days and confirm your own domains have vanished from the referral report.