Google Analytics 4 Cross-Domain Tracking | OpsBlu Docs

Google Analytics 4 Cross-Domain Tracking

Requirements when journeys span multiple domains or apps for Google Analytics 4.

Overview

Cross-domain tracking in Google Analytics 4 ensures user sessions persist when visitors navigate between domains you own. GA4 uses the _gl linker parameter to pass client identifiers across domain boundaries, preventing session fragmentation and preserving accurate attribution.

When Cross-Domain Tracking Is Required

  • Separate checkout domains: Main site on www.example.com, checkout on checkout.example.com
  • Third-party payment processors: Redirects to payment gateways (Stripe, PayPal) that return users to confirmation pages
  • Regional or brand domains: example.com, example.co.uk, brand.example.com
  • Microsites and landing pages: Campaign-specific domains that funnel to conversion points
  • App-to-web experiences: Mobile app links opening web views on different domains

Configuration Methods

Google Tag Manager Setup

  1. Navigate to your GA4 Configuration tag
  2. Expand Configure tag settings > More Settings > Cross-domain measurement
  3. Add all domains that should share sessions:
    • example.com
    • checkout.example.com
    • payments.thirdparty.com
  4. Enable Enable cross-domain measurement

Alternatively, configure in the data stream settings:

  1. Go to Admin > Data Streams > [Your Stream] > Configure tag settings
  2. Click Configure your domains
  3. Add match conditions for each domain

gtag.js Direct Implementation

gtag('config', 'G-XXXXXXXXXX', {
  linker: {
    domains: ['example.com', 'checkout.example.com', 'partner.com'],
    accept_incoming: true,
    decorate_forms: true
  }
});

Domain Configuration Options

Option Description
domains Array of domains to include in cross-domain linking
accept_incoming Accept linker parameters from other domains (default: true)
decorate_forms Add linker to form submissions, not just links
url_position Where to place the _gl parameter (query or fragment)

Referral Exclusion Configuration

Prevent internal domains from appearing as referral traffic sources:

  1. Go to Admin > Data Streams > [Your Stream] > Configure tag settings
  2. Click List unwanted referrals
  3. Add match conditions:
    • Match type: Contains
    • Domain: checkout.example.com

Without referral exclusions, users returning from checkout or payment domains will start new sessions, breaking attribution.

How the Linker Works

When a user clicks a cross-domain link:

  1. GA4 detects the link destination matches a configured domain
  2. The _gl parameter is appended with encoded client/session data
  3. The destination domain reads the parameter and restores the session

Example decorated URL:

https://checkout.example.com/cart?_gl=1*abc123*_ga*MTIzNDU2Nzg5MA..*_ga_XXXXXXXX*MTY4...

The _gl parameter contains:

  • Client ID (_ga)
  • Session ID and timestamp
  • Cross-domain linking metadata

Third-Party Checkout Integration

When using external payment providers:

Supported Flow

example.com → stripe.com → example.com/confirmation
  1. Pre-redirect: Store the GA client_id in a server session or URL parameter
  2. Payment callback: Include the _gl parameter in the return URL
  3. Confirmation page: GA4 reads the linker and restores the session

Configuration for Payment Providers

Most payment providers support custom return URLs:

// Stripe checkout session
const session = await stripe.checkout.sessions.create({
  success_url: 'https://example.com/success?session_id={CHECKOUT_SESSION_ID}&_gl=' + getGALinker(),
  cancel_url: 'https://example.com/cart'
});

Retrieve the linker parameter:

function getGALinker() {
  return new URLSearchParams(window.location.search).get('_gl') || '';
}

Edge Cases and Considerations

iFrame Embeds

When content is embedded via iframes across domains:

  • Parent and child frames need separate GA4 instances
  • Use postMessage to pass client_id between frames
  • Consider whether iframe tracking genuinely adds value

Single Page Applications (SPAs)

Ensure the linker decorator attaches to dynamically rendered links:

// After SPA navigation or dynamic content load
gtag('event', 'page_view', {
  page_location: window.location.href,
  page_title: document.title
});

Safari ITP and privacy extensions may strip URL parameters:

  • Monitor cross-domain conversion rates for drops indicating blocking
  • Implement server-side session stitching as a fallback
  • Use first-party subdomains where possible

Cross-domain linking respects Consent Mode settings:

  • With analytics_storage: denied, the linker still works but uses cookieless pings
  • Client identity may be less persistent without cookies
  • Ensure consent state is consistent across all domains

Validation and Testing

GTM Preview Mode

  1. Enable GTM Preview on the source domain
  2. Click a cross-domain link
  3. Verify the _gl parameter appears in the URL
  4. Open GTM Preview on the destination domain
  5. Confirm the same client_id appears in both contexts

GA4 DebugView

  1. Enable DebugView in GA4 (Admin > DebugView)
  2. Install the GA Debugger browser extension
  3. Navigate through the cross-domain flow
  4. Verify session_start only fires once at the journey start
  5. Confirm client_id remains consistent across domains

Network Tab Inspection

Check that the linker parameters persist:

  1. Open browser DevTools > Network
  2. Click a cross-domain link
  3. Inspect the request URL for _gl parameter
  4. On the destination, verify the collect request includes the restored client_id

Real-Time Reports

After implementing:

  1. Open GA4 Real-Time reports
  2. Navigate through the cross-domain journey
  3. Confirm a single user appears moving through pages on different domains
  4. Check that traffic source attribution is preserved

Troubleshooting

Symptom Likely Cause Solution
Sessions split at domain boundary Domain not in linker list Add domain to cross-domain configuration
Internal domain shows as referral Missing referral exclusion Add domain to unwanted referrals list
_gl parameter missing on links Linker not configured Enable cross-domain measurement in GTM or gtag
Different client_id after redirect accept_incoming disabled Ensure destination accepts linker parameters
Payment return loses session Return URL missing _gl Pass linker parameter through payment flow
Safari users losing sessions ITP blocking Implement server-side fallback

BigQuery Validation

For sites with BigQuery export enabled, validate cross-domain tracking with SQL:

SELECT
  user_pseudo_id,
  event_name,
  (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'page_location') AS page_location,
  event_timestamp
FROM `project.analytics_XXXXXX.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20240101' AND '20240131'
  AND user_pseudo_id = 'your_test_client_id'
ORDER BY event_timestamp;

This query reveals the full journey with consistent user_pseudo_id across domains.