Overview
Cross-domain tracking enables Google Ads to maintain click attribution when users navigate between multiple domains in your conversion funnel. This is essential for scenarios like:
- Main website to separate checkout domain
- Marketing site to application subdomain
- Multiple country-specific domains
- Third-party payment processors
Implementation Methods
Auto-Link Domains (gtag.js)
Configure automatic cross-domain linking in the global site tag:
gtag('config', 'AW-CONVERSION_ID', {
'linker': {
'domains': ['example.com', 'checkout.example.com', 'app.example.com']
}
});
This automatically appends _gl parameter to links between specified domains, preserving the GCLID.
Google Tag Manager Setup
Step 1: Configure Auto-Link Variable
- Create new Variable: Auto-Link Domains
- Type: Auto-Link Domains
- Add domains:
example.com,checkout.example.com - Check "Use hash as delimiter"
- Check "Decorate forms"
Step 2: Update Google Ads Tag
- Open Google Ads Conversion Tracking tag
- Enable "Cross-Domain Tracking"
- Select the Auto-Link Domains variable
- Save and publish
Step 3: Configure All Domains
Repeat configuration on all domains in the funnel with the same domain list.
Manual Link Decoration
For specific links that need decoration:
// Decorate a specific link
var link = document.getElementById('checkout-link');
var linker = new gtag.Linker(['example.com', 'checkout.example.com']);
link.href = linker.decorate(link.href);
Form Decoration
Automatically decorate forms that submit to other domains:
gtag('config', 'AW-CONVERSION_ID', {
'linker': {
'domains': ['example.com', 'checkout.example.com'],
'decorate_forms': true
}
});
Third-Party Payment Processors
PayPal, Stripe, Square
For payment processors that redirect users:
- Add payment processor domain to linker domains (if they allow)
- Implement return URL tracking
- Use server-side conversion tracking as backup
Note: Most payment processors don't allow JavaScript execution, making client-side cross-domain tracking impossible. Use server-side conversion imports instead.
Recommended Approach
// Track before redirect to payment processor
gtag('event', 'begin_checkout', {
'send_to': 'AW-CONVERSION_ID',
'transaction_id': 'TXN_12345',
'value': 99.99,
'currency': 'USD'
});
// Server-side: Import conversion after payment confirmation
// Use Google Ads API to upload offline conversions with GCLID
Subdomain Tracking
For subdomains (e.g., www.example.com and app.example.com):
Cookie Domain Configuration
gtag('config', 'AW-CONVERSION_ID', {
'cookie_domain': '.example.com', // Note the leading dot
'linker': {
'domains': ['www.example.com', 'app.example.com']
}
});
The leading dot (.example.com) allows cookies to be shared across all subdomains.
Multiple Top-Level Domains
For separate TLDs (e.g., example.com and example.co.uk):
gtag('config', 'AW-CONVERSION_ID', {
'linker': {
'domains': ['example.com', 'example.co.uk', 'example.de'],
'accept_incoming': true
}
});
Deploy this configuration on all domains with the complete list.
Testing Cross-Domain Tracking
Verify Link Decoration
- Navigate to source domain
- Click link to destination domain
- Check URL contains
_glparameter:https://checkout.example.com/?_gl=1*abc123...
Verify GCLID Transfer
- Click Google Ad with test GCLID
- Navigate across domains
- Check GCLID persists in cookies and URL parameters
- Use Google Tag Assistant to verify
Chrome Console Test
// Check if linker is working
document.querySelectorAll('a').forEach(link => {
if (link.href.includes('_gl=')) {
console.log('Decorated link:', link.href);
}
});
GTM Preview Mode Testing
- Enable GTM Preview mode on source domain
- Click through to destination domain
- Verify GTM Preview continues on destination
- Check Data Layer for GCLID values
- Confirm conversions fire with correct attribution
Common Issues & Solutions
_gl Parameter Not Appearing
Causes:
- Domains not configured in linker settings
- JavaScript loading after link click
- Conflicting scripts removing URL parameters
Solutions:
- Verify domain list includes all domains (with and without www)
- Load gtag.js in
<head>before content - Check for URL sanitization scripts
GCLID Not Persisting
Causes:
- Cookie domain mismatch
- Third-party cookie blocking
- Session timeout
Solutions:
- Set
cookie_domaincorrectly for subdomains - Use first-party cookies only
- Extend GCLID cookie lifetime:
gtag('config', 'AW-CONVERSION_ID', {
'cookie_expires': 7776000 // 90 days in seconds
});
Conversions Not Attributed
Causes:
- GCLID lost during redirect
- Conversion fires before GCLID extracted
- Missing
accept_incomingparameter
Solutions:
- Add
accept_incoming: trueto linker config - Delay conversion tag until GCLID is processed
- Implement server-side conversion tracking
Advanced Configuration
Conditional Cross-Domain Tracking
Only decorate links to specific domains:
document.addEventListener('click', function(event) {
var link = event.target.closest('a');
if (link && link.hostname === 'checkout.example.com') {
var linker = new gtag.Linker(['checkout.example.com']);
link.href = linker.decorate(link.href);
}
});
SPA (Single Page Application) Tracking
// Update linker on route change
router.afterEach((to, from) => {
gtag('config', 'AW-CONVERSION_ID', {
'page_path': to.path,
'linker': {
'domains': ['example.com', 'app.example.com']
}
});
});
Server-Side Cross-Domain Tracking
For server-rendered applications:
- Extract GCLID from URL or cookie server-side
- Store in session or database
- Include in conversion API calls
- Use Google Ads API for offline conversion import
# Python example
from flask import request, session
@app.route('/checkout')
def checkout():
gclid = request.args.get('gclid') or request.cookies.get('_gcl_aw')
if gclid:
session['gclid'] = gclid
return render_template('checkout.html')
@app.route('/conversion')
def conversion():
gclid = session.get('gclid')
if gclid:
# Send conversion to Google Ads API with GCLID
send_offline_conversion(gclid, conversion_data)
Best Practices
- Include all domains in the linker configuration, including www and non-www versions
- Test cross-domain tracking in staging before production deployment
- Use
accept_incoming: trueon all domains to receive decorated links - Set
cookie_domainfor subdomain tracking - Monitor conversion attribution in Google Ads reports
- Document your cross-domain setup for future reference
- Use server-side tracking for critical conversions
- Implement both client-side and server-side tracking for redundancy
- Regularly test link decoration after site updates
- Consider using Google Analytics 4 cross-domain tracking in parallel for validation