The Problem
Your booking or checkout flow lives on a different domain. A user lands on your site, clicks “Book Now,” and is sent to SimplyBook.me, Calendly, a WooCommerce checkout subdomain, or Typeform.
GA4 sees this as a brand new session from a referral source. Your original attribution - paid search, organic, referral - is replaced with the third-party domain. The user you spent money acquiring looks like a direct or referral visit by the time they convert.
Your conversion data is attributed to the wrong source. Your Google Ads ROAS is understated. Your actual traffic sources look worse than they are.
Why Cross-Domain Tracking Breaks
GA4 identifies users via a client_id stored in the _ga cookie. Cookies are domain-scoped - a cookie set on yourdomain.com is not accessible on simplybook.me.
When the user navigates to the third-party domain, GA4 cannot read their existing client_id. It generates a new one. A new session starts with the referrer set to your domain.
The solution is to pass the client_id from your domain to the third-party domain via a URL parameter - specifically the _gl parameter that GA4’s linker protocol uses.
Scenario 1: Redirect-Based Third-Party Checkouts (Calendly, Typeform, SimplyBook as Redirect)
When the user clicks a link that takes them to a third-party domain, GA4’s cross-domain linker can append the _gl parameter to the URL automatically.
GA4 Native Cross-Domain Setup
Step 1: Configure domains in GA4
GA4 → Admin → Data Streams → your stream → Configure tag settings → Configure your domains
Add every domain involved in your user journey:
yourdomain.comsimplybook.me(or your specific booking subdomain)calendly.com- Any other domain in the flow
Step 2: Enable cross-domain linking in GTM
In your Google Tag (base configuration) in GTM, add a configuration field:
- Field name:
linker - Value:
{"domains": ["yourdomain.com", "simplybook.me", "calendly.com"]}
Or use the dedicated Linker configuration in the Google Tag settings:
- Tag → Fields to Set → add
linkerwithaccept_incoming: true
When this is configured, GA4 automatically appends ?_gl=... to outbound links pointing to the domains you listed. When the user lands on the third-party domain, that _gl parameter is read and the existing client_id is restored.
Verify it is working: Click a link to your booking page and inspect the URL in the browser address bar. You should see ?_gl= appended. If you do not, the linker is not functioning.
Scenario 2: Iframe-Embedded Tools (SimplyBook Widget, Typeform Embed, Calendly Inline)
This is significantly harder.
When a third-party tool is embedded as an iframe on your page, the _gl parameter approach does not work. The browser’s same-origin policy prevents the parent page (your domain) and the iframe content (third-party domain) from sharing cookies or URL parameters directly.
The iframe lives in its own isolated context. The third-party’s GA4 instance inside the iframe cannot read the client_id from your domain’s GA4 instance.
What Does Not Work
- Cross-domain linker: the linker appends
_glto links, not to iframe URLs document.referrer: blocked by iframe sandboxing- Cookies: blocked by same-origin policy
What Does Work: postMessage
The browser’s window.postMessage API allows controlled communication between a parent page and an iframe, even across domains - if the iframe is configured to listen for it.
This requires the third-party tool to support receiving and acting on messages. Most embedded tools do not support this natively.
For tools that do support it (or for custom-built iframes your developer controls), the approach is:
Parent page - send client_id to iframe:
// Get the GA4 client_id from the cookie
function getClientId() {
const match = document.cookie.match(/_ga=GA\d+\.\d+\.(\d+\.\d+)/);
return match ? match[1] : null;
}
// Wait for the iframe to load, then send the client_id
window.addEventListener('load', function() {
const iframe = document.querySelector('iframe[src*="yourbookingdomain.com"]');
if (iframe && getClientId()) {
iframe.contentWindow.postMessage(
{ type: 'ga4_client_id', client_id: getClientId() },
'https://yourbookingdomain.com'
);
}
});
Iframe (booking domain) - receive and apply client_id:
window.addEventListener('message', function(event) {
if (event.origin !== 'https://yourmainsite.com') return; // security check
if (event.data.type === 'ga4_client_id') {
// Configure GA4 with the received client_id
gtag('config', 'G-XXXXXXXXXX', {
client_id: event.data.client_id
});
}
});
This only works if you control both sides of the communication - or if the tool provider explicitly supports this integration pattern.
Scenario 3: SimplyBook.me with Offline Conversion Import
For SimplyBook.me specifically, there is an alternative that avoids the iframe problem entirely: Offline Conversion Import.
Instead of tracking the conversion at the moment the booking is made inside the iframe, you:
- Capture the user’s
gclid(Google Click ID) when they land on your site via Google Ads - Store it in a first-party cookie or your CRM
- When SimplyBook.me sends a booking webhook, include the
gclidin the data you send to Google Ads via the Offline Conversion API
This bypasses cross-domain tracking entirely. The conversion is attributed server-side using the click ID, with no dependency on cookies crossing domains.
This approach requires:
- A way to capture and store
gclidon your site (GTM + custom HTML tag + cookie) - SimplyBook.me webhooks configured to send booking data
- A server or Zapier/Make automation to forward the data to the Google Ads Conversion API
It is more technical but more reliable than any client-side iframe workaround.
Scenario 4: WooCommerce or Custom Checkout on a Subdomain
Subdomains (checkout.yourdomain.com) are treated as separate domains by cookie settings by default.
The fix: Configure the _ga cookie to be set on the root domain rather than the subdomain.
In your Google Tag configuration (via GTM), add:
- Field name:
cookie_domain - Value:
yourdomain.com(the root domain without the subdomain prefix)
This makes the _ga cookie accessible across all subdomains of yourdomain.com, including checkout.yourdomain.com. No linker parameter is needed for subdomain setups when the cookie domain is configured correctly.
Also configure in GA4 → Admin → Data Streams → Configure tag settings → Configure your domains - add both the root domain and the subdomain.
How to Verify Cross-Domain Tracking Is Working
Test 1: Open your site via a paid Google Ads click. Navigate to the booking or checkout flow on the third-party domain. Complete a test conversion. In GA4 → Realtime, check the source/medium of the conversion - it should show google / cpc (or whatever your original source was), not the third-party domain name.
Test 2: In Chrome DevTools, before clicking through to the third-party domain, note the _ga cookie value. After landing on the third-party domain, check the _ga cookie value there. If cross-domain is working, the client_id portion should match.
Test 3: Inspect the URL when you click a link to the third-party domain. The _gl parameter should be appended automatically if the cross-domain linker is configured correctly.
What to Tell Clients
When explaining this to clients or stakeholders:
“When users move from your site to [booking tool], Google Analytics loses track of where they originally came from. This makes Google Ads look less effective than it actually is. We can fix this by configuring cross-domain tracking - a setting that passes the user’s identity between the two systems so the original traffic source is preserved.”
Keep it attribution-focused. The business impact (wrongly attributed conversions, underreported ROAS) is what gets attention.
Final Thoughts
Cross-domain tracking is one of the most common sources of attribution data loss. It is not a glamorous problem - no one builds features around it - but it consistently undermines reporting accuracy for businesses that use third-party tools in their conversion flow.
Fix the subdomain issue with cookie_domain. Fix the redirect-based third-party flow with the cross-domain linker. For iframes, use postMessage if the tool supports it - or bypass the problem entirely with Offline Conversion Import.
In the next article of this series, we will cover:
Related Posts
Duplicate Conversions in GTM - Why Your Purchase Event Fires Twice and How to Diagnose It
9 min read
WooCommerce Google Ads Conversion Tracking via GTM Using GTM4WP
14 min read
GTM on Single-Page Applications - Why Only the First Pageview Gets Tracked and How to Fix It
10 min read
Need Help With Your Google Ads?
I help e-commerce brands scale profitably with data-driven PPC strategies.
Get In Touch