Cross-Domain Tracking Issues
What This Means
Cross-domain tracking allows analytics platforms to recognize the same user as they navigate between different domains (e.g., from example.com to checkout.example.net). When cross-domain tracking fails, each domain appears as a separate session, causing:
- Inflated user counts
- Lost referral data
- Broken conversion attribution
- Inaccurate customer journeys
Impact on Your Business
Analytics Accuracy:
- Users counted multiple times - One visitor appears as 2+ users
- Self-referrals - Your own domains show as traffic sources
- Lost attribution - Marketing source data breaks at domain boundary
- Incorrect funnels - User journey appears fragmented
Marketing ROI:
- Conversions attributed to wrong source
- Campaign performance looks worse than reality
- Retargeting audiences become inaccurate
- Customer lifetime value calculations fail
Business Decisions:
- Misleading data leads to wrong decisions
- Marketing spend misallocated
- User experience issues go undetected
How to Diagnose
Method 1: Check for Self-Referrals in GA4
- Open Google Analytics 4
- Navigate to Reports → Acquisition → Traffic acquisition
- Look for your own domains in the "Session source/medium" report
- If you see
yourdomain.com / referral- cross-domain is broken
Method 2: Inspect Client ID Across Domains
On domain A, run in console:
// Get GA4 client ID
gtag('get', 'G-XXXXXXXXXX', 'client_id', (clientId) => {
console.log('Domain A Client ID:', clientId);
});
Click a link to domain B, then run the same code.
If client IDs differ, cross-domain tracking isn't working.
Method 3: Check URL Parameters
When clicking a link to another domain:
- Hover over a cross-domain link
- Check if URL contains
_glparameter (GA4) or_gaparameter (UA) - Click the link and inspect the landing URL
Working cross-domain URL:
https://checkout.example.com/cart?_gl=1*1abc123*_ga*MTIzNDU2Nzg5*_ga_XXXXXXXXXX*MTY0MDAwMDAwMC4x
If no _gl parameter, cross-domain isn't configured.
Method 4: GA4 DebugView
- Enable debug mode on both domains
- Navigate across domains
- In GA4 DebugView, check if
session_startfires on each domain - Multiple
session_startevents = cross-domain broken
Method 5: GTM Preview Mode
- Start GTM Preview on domain A
- Click cross-domain link
- Check if Preview mode continues on domain B
- If preview breaks, linker isn't working
Common Causes
1. Missing Cross-Domain Configuration
GA4 needs explicit cross-domain setup for each domain pair.
2. Links Not Being Decorated
The linker script isn't adding parameters to outbound links.
3. Wrong Domain Format
Using www.example.com vs example.com inconsistently.
4. JavaScript Errors Blocking Linker
Errors before the linker runs prevent decoration.
5. Links Opening in New Windows
Some configurations don't handle target="_blank" links.
6. Form Submissions Crossing Domains
Forms need special handling for cross-domain tracking.
7. Redirects Stripping Parameters
Server redirects removing the _gl parameter.
8. Cookie Consent Blocking
CMP blocking cookies before linker runs.
General Fixes
Fix 1: Configure GA4 Cross-Domain Tracking
In GA4 Admin:
- Navigate to Admin → Data Streams
- Click on your web stream
- Click Configure tag settings
- Click Configure your domains
- Add all domains that need cross-domain tracking:
example.comcheckout.example.netshop.example.com
Contains- Matches any URL containing the domainEquals- Exact match onlyStarts with- URL prefix match
Fix 2: Configure GTM Linker
If using Google Tag Manager:
- Open your GTM container
- Edit your GA4 Configuration tag
- Add Fields to Set:
- Field Name:
linker - Value:
{"domains": ["example.com", "checkout.example.net"]}
- Field Name:
Or use separate Linker tag:
{
"domains": ["example.com", "checkout.example.net", "shop.example.com"],
"accept_incoming": true,
"url_position": "query"
}
Fix 3: Manual gtag.js Configuration
If implementing directly:
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX', {
'linker': {
'domains': ['example.com', 'checkout.example.net', 'shop.example.com'],
'accept_incoming': true
}
});
</script>
Fix 4: Handle Forms Crossing Domains
Forms need special treatment:
// Decorate form action URLs
gtag('config', 'G-XXXXXXXXXX', {
'linker': {
'domains': ['checkout.example.com'],
'decorate_forms': true
}
});
Or manual form decoration:
document.querySelectorAll('form[action*="checkout.example.com"]').forEach(form => {
form.addEventListener('submit', function() {
gtag('get', 'G-XXXXXXXXXX', 'client_id', function(clientId) {
const url = new URL(form.action);
url.searchParams.set('_gl', generateLinkerParam(clientId));
form.action = url.toString();
});
});
});
Fix 5: Exclude Referrals from Your Domains
In GA4:
- Navigate to Admin → Data Streams
- Click on your web stream
- Click Configure tag settings
- Click List unwanted referrals
- Add all your domains:
example.comcheckout.example.net
Fix 6: Handle Subdomain Tracking
For subdomains of the same root domain:
gtag('config', 'G-XXXXXXXXXX', {
'cookie_domain': '.example.com', // Note the leading dot
'linker': {
'domains': ['www.example.com', 'shop.example.com', 'blog.example.com']
}
});
Fix 7: Debug and Verify Linker
Add debug logging:
// Check if linker is decorating links
document.querySelectorAll('a[href*="checkout.example"]').forEach(link => {
link.addEventListener('click', function(e) {
console.log('Link href:', this.href);
// Should contain _gl parameter
});
});
// Check incoming linker parameter
const urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('_gl')) {
console.log('Incoming linker:', urlParams.get('_gl'));
}
Fix 8: Handle Redirects
Ensure server redirects preserve query parameters:
Apache (.htaccess):
# Preserve query string in redirects
RewriteRule ^old-page$ /new-page [R=301,L,QSA]
Nginx:
# Preserve query string
rewrite ^/old-page$ /new-page permanent;
Meta Pixel Cross-Domain
Configure fbq for Multiple Domains
fbq('init', 'YOUR_PIXEL_ID', {}, {
agent: 'your-agent-string'
});
// Enable cross-domain with external_id
fbq('init', 'YOUR_PIXEL_ID', {
external_id: getCrossDomainUserId() // Your user identifier
});
Use First-Party Cookies
// Set consistent user ID across domains using server-side
fbq('init', 'YOUR_PIXEL_ID', {
external_id: 'USER_123', // Server-provided consistent ID
em: 'hashed_email' // Hashed user email for matching
});
Platform-Specific Guides
| Platform | Troubleshooting Guide |
|---|---|
| Shopify | Shopify Cross-Domain Guide |
| WordPress | WordPress Cross-Domain Guide |
| Magento | Magento Cross-Domain Guide |
Verification
After implementing cross-domain tracking:
Test the link decoration:
- Click a link to another domain
- Verify
_glparameter appears in URL - Check parameter persists after page load
Verify Client ID consistency:
// Run on both domains after navigation gtag('get', 'G-XXXXXXXXXX', 'client_id', console.log); // Should show same IDCheck GA4 reports:
- Wait 24-48 hours for data
- Verify self-referrals are gone
- Check user count is realistic
Test user journey:
- Start on domain A
- Navigate to domain B
- Complete conversion
- Verify single session in GA4
Common Mistakes
- Forgetting www vs non-www - Treat as separate domains
- Not including all domains - Missing one breaks the chain
- Incorrect match conditions - "Contains" vs "Equals"
- Not testing forms - Only testing regular links
- Ignoring new tabs -
target="_blank"needs handling - Redirect stripping params - Server config issues
- Cookie consent timing - Linker runs before consent
- Subdomain cookie scope - Need root domain cookie
- Multiple GA4 properties - Each needs configuration
- Testing in same browser session - Use incognito for clean tests
Cross-Domain Checklist
Pre-Implementation:
[ ] List all domains involved
[ ] Identify domain transition points (links, forms, redirects)
[ ] Document current user/session counts for comparison
Configuration:
[ ] Add all domains to GA4 cross-domain settings
[ ] Configure referral exclusions
[ ] Set up GTM linker (if using GTM)
[ ] Enable form decoration if needed
Testing:
[ ] Test in incognito/private browsing
[ ] Verify _gl parameter appears on outbound links
[ ] Confirm client ID matches across domains
[ ] Check forms work correctly
[ ] Test new tab/window links
Verification:
[ ] Monitor for self-referrals in GA4
[ ] Compare user counts before/after
[ ] Verify conversion attribution works
[ ] Check campaign tracking maintains source