TL;DR
- Cross-domain setup lives in Admin > Data streams > Configure tag settings > Configure your domains, with up to 100 OR conditions.
- Every domain must load the same G- tag ID from the same web data stream, or the IDs passed in _gl never join up.
- Domains you cannot tag, like many payment pages, go in List unwanted referrals, which holds up to 50 entries per stream.
- Redirects that drop the _gl parameter and scripts that call Event.stopPropagation() on clicks can stop the IDs reaching the destination.
GA4 cross-domain tracking lets Google Analytics treat a visitor who moves from one of your domains to another, for example from your hotel website to a booking engine on a different domain, as one user in one session instead of two strangers. You set it up in the web data stream's tag settings under "Configure your domains", and it only works when every domain in the journey loads the same Google tag ID.
Without it, the second domain sees a brand new visitor. The session that started with a Google Ads click ends at the booking engine, and the purchase that follows is credited to a referral from your own website. Revenue looks like it came from nowhere, paid campaigns look weaker than they are, and your own domain shows up as a top traffic source. This guide covers when you need the setting, how to configure it, what the _gl parameter does, and the specific ways it breaks.
When you need cross-domain measurement
You need it when a single customer journey crosses a domain boundary and you control the tag on both sides. Analytics stores its client ID in a first-party cookie, and browsers do not share cookies between different registrable domains. So example.com cannot read the cookie set on example-booking.com, and each domain mints its own ID.
Common cases where this matters:
- A hotel or tour operator that sends guests from its main site to a booking engine hosted on the vendor's domain, where the vendor lets you add your own Google tag.
- A brand that runs its content site on one domain and its shop on another, such as a .com for the brand and a separate domain for checkout.
- A business that bought a second domain for a campaign microsite and links from it to the main site.
- A multi-country setup where each market has its own domain but you report all of them in one property.
If you cannot install your Google tag on the other domain, cross-domain measurement is not possible there. Many payment gateways fall into this group. For those, the fix is different and is covered in the referrals section below.
How to configure your domains in the Google tag
The setting lives in the GA4 interface, not in Google Tag Manager, and Google recommends the interface over manual code. You need the Editor role or higher.
- In Admin, under Data collection and modification, click Data streams.
- Click Web, then click the web data stream that collects data for your site.
- At the bottom of the stream details, click Configure tag settings.
- In the Settings section, click Configure your domains.
- Accept any domains Google lists under Recommendations, or click Add condition under "Include domains that match the following conditions".
- Choose a match type, enter the domain, repeat for every domain in the journey, then click Save.
List all of the domains, including the one the stream was created for. Conditions are evaluated with OR logic, so a link is decorated if its destination matches any one of them, and you can add up to 100 conditions. A "contains" condition such as example-booking.com covers its subdomains too, but be careful with short strings: a loose condition can match domains you do not own.
The other half of the requirement is easy to miss. Every domain must load the same "G-" tag ID from the same web data stream. If the booking engine is tagged with a different measurement ID, or sends data to a separate property, the configuration does nothing useful because the two sides are not reading the same measurement. Ask the vendor exactly which ID their template loads and check it in the page source or in Tag Assistant.
Google also supports a manual setup through the gtag.js "get" and "config" commands. That route is for sites that cannot use the automatic linker, and it is easy to get subtly wrong, so treat it as a last resort.
What the _gl linker parameter does
Once your domains are configured, the Google tag watches for clicks on links, and for form submissions, that lead to one of the listed domains. Just before the browser leaves, it appends a parameter called _gl to the destination URL. The value carries the cookie IDs from the first domain, so a decorated URL looks something like example-booking.com/rooms?_gl=1*abc123*...
When the tag loads on the destination page, it reads _gl, writes the same IDs into the cookies on that domain, and carries on. Analytics then sees one user and one session spanning both domains. The tag adds the parameter at the moment of the click. It is not something to paste into ads or emails by hand.
Forms count as well as links. A search widget on your homepage that submits to the booking engine's domain gets decorated in the same way, as long as the form submits normally and is not replaced by a script that builds its own URL.
Self-referrals and the unwanted referrals list
A self-referral is your own domain, or a domain in your own journey, showing up as the source of a session. It happens when a visitor arrives on a second domain without a valid _gl parameter: Analytics sees a referrer from the first domain and records a new session with that domain as the source. The original source, such as google / cpc, is lost for everything that happens next.
When cross-domain is working, Analytics stops treating the cross-domain hop as a referral because the landing page carries the _gl parameter. Google's help page ties this to the _gl parameter on the landing page, so a hop that arrives without it can still be recorded as a referral.
For domains you cannot tag, use the unwanted referrals list. The path is Admin, Data collection and modification, Data streams, Web, your stream, Configure tag settings, then Show all in the Settings section and List unwanted referrals. When a session arrives from a matching referrer, Analytics adds ignore_referrer=true to the event, which tells it not to show that referrer as a traffic source. A stream can hold up to 50 unwanted referrals.
The classic case is a payment processor. The guest pays on a third-party page and is redirected back to your confirmation page. Without the exclusion, the purchase is credited to the payment provider's domain. With it, the session keeps its original attribution. One caveat from Google's own documentation: if a user arrived from that domain before you added the exclusion and later returns directly, the last non-direct click model can still attribute the return session to that domain.
Subdomains versus separate domains
Subdomains of the same domain, such as www.example.com and shop.example.com, behave differently. By default the Google tag writes its cookie at the highest domain level it can, so every subdomain can read the same cookie and the same client ID. A reasonable inference from that default is that subdomains often work without extra settings, but Google's help page still recommends the cross-domain setup for subdomains, so treat this as a reading of the cookie behaviour, not a Google rule.
That default can be broken. If someone changed the cookie domain setting on one subdomain, or a subdomain runs a different tag setup, moving between them can create self-referrals. Google's guidance for that case is to tag every page, configure cross-domain measurement on all pages, use the same cookie domain across subdomains, and add the subdomains to the exclusion list if referrals persist.
Separate registrable domains, such as example.com and example.co.th or example-booking.com, always need the configuration, because no cookie can be shared between them.
The table below sums up which setups need what.
| Journey | What to configure | Why |
|---|---|---|
| www.example.com to shop.example.com | Check for self-referrals; Google recommends the cross-domain setup here too | Subdomains can share the default cookie, but a changed cookie domain setting breaks that |
| example.com to a booking engine on another domain that loads your G- tag | Add both domains under Configure your domains | Different domains cannot share cookies, so the _gl parameter has to carry the IDs |
| example.com to a payment page you cannot tag | Add the payment domain to List unwanted referrals | Cross-domain is impossible without your tag, so stop the return visit counting as a referral |
| Booking widget embedded in an iframe on your page | Check with the vendor | Inference: Google describes the linker for links and forms, and an iframe loaded in place is neither |
Testing with Tag Assistant and DebugView
Test before you trust any report. The quickest check is manual and needs no tools:
- Open a page on the first domain that links or submits to the second domain.
- Click the link or submit the form.
- Confirm the destination page loads normally.
- Look at the address bar and confirm the URL contains _gl, for example ?_gl=1*...
- If your site offers file downloads that cross domains, confirm a download still starts from a page carrying the parameter.
Then confirm the data side. Start a Tag Assistant session at tagassistant.google.com, which puts your browser in debug mode by adding a parameter to the site address, and walk the same journey. Open DebugView in GA4. The seconds stream shows events from the last 60 seconds and the minutes stream keeps the last 30 minutes. You want to see your page views on both domains in the same device stream, with no break where a new session begins at the second domain.
After a few days of normal traffic, open the Traffic acquisition report and look for your own domains, or your booking engine's domain, under session source. A steady stream there means some path is still not decorated.
Common breakages
Redirects that strip parameters
If the destination redirects, for example from http to https, from a short URL to a long one, or from a language selector to a locale path, and the redirect drops the query string, _gl is gone before the tag can read it. Check every hop with your browser's network panel. The fix belongs on the server or in the vendor's redirect rules, which must pass query parameters through.
JavaScript navigation
Buttons that navigate with a script instead of a real link, and scripts that call Event.stopPropagation() on clicks, can stop the tag from decorating the URL. Changing it to a plain anchor element with an href usually solves it.
Iframes
Many booking engines can be embedded as an iframe on your page. Google's cross-domain help page describes the linker for links and forms and does not cover iframes, so the inference is that an iframe loaded in place is not decorated. Ask the vendor how its embed handles Google Analytics. If it cannot support your measurement, linking out to a full page on its domain is usually easier to measure correctly.
Mismatched tag IDs
The vendor's template loads an old ID, a different property, or no tag at all on the confirmation step. The _gl parameter arrives intact but nothing on the other side reads it into the right stream.
Consent banners
If the second domain blocks analytics cookies until a visitor accepts its own consent banner, the tag behaves differently until consent is given. Run your test with consent accepted and declined, and make sure both domains handle consent consistently.
What this means for Thai marketers
A Thai hotel, resort, tour operator or clinic that runs its main site on one domain and takes bookings through a third-party engine, or a brand that keeps a .com and a .co.th side by side, splits sessions by default. For a hotel spending on Google Ads, a broken handoff to the booking engine can make paid search look like it produces almost no revenue, which pushes budget decisions in the wrong direction. Before you judge campaign return, check the handoff using the steps above. If you run a hotel and want the whole measurement chain checked, the hotel marketing team can look at it as part of the campaign work.
FAQ
Do I need GA4 cross-domain tracking for subdomains?
Google's help page recommends the setup for subdomains too, because moving between subdomains with different cookie domain settings can create self-referrals. Subdomains can share the Google tag's default cookie, so watch session source for your own subdomains and check cookie domain settings if they appear.
Does cross-domain measurement work if the other domain uses a different measurement ID?
No, every domain must load the same G- tag ID from the same web data stream. A different ID sends data to another stream or property, so the IDs passed in _gl never join up in your reports.
Why do I still see my booking engine as a referral after setting it up?
Some path to the booking engine is arriving without the _gl parameter. Look for redirects that drop the query string, buttons that navigate with JavaScript, iframe embeds, and return trips from payment pages that need an entry in the unwanted referrals list.
Does the change fix my historical data?
No. The linker works when a visitor navigates, so it can only affect sessions collected after you save the setting. Past sessions keep the split attribution, so compare periods carefully around the date you made the change.
Getting the handoff right
Cross-domain measurement is a small setting with a large effect on attribution. Configure every domain, confirm the same tag ID runs on each one, test the real journeys, and keep the unwanted referrals list for the domains you cannot tag. If you would rather have the setup checked end to end, the GA4 setup and migration service covers data streams, tags and attribution. Clean data also changes how you read Google Ads campaigns, and a technical SEO audit is a good moment to catch redirects that strip parameters from your URLs.






