Cross-Browser Tracking Issues | Blue Frog Docs

Cross-Browser Tracking Issues

How to test and troubleshoot analytics across different browsers and privacy features

Cross-Browser Tracking Issues

What This Means

Cross-browser tracking issues occur when analytics tags work correctly in one browser (usually Chrome) but fail or behave differently in others. This is increasingly common as browsers implement different privacy protections:

  • Safari ITP (Intelligent Tracking Prevention) - Limits cookie lifespan and third-party tracking
  • Firefox ETP (Enhanced Tracking Protection) - Blocks known trackers and third-party cookies
  • Brave Browser - Aggressive blocking of ads and trackers by default
  • Edge Tracking Prevention - Similar protections to Safari ITP
  • Cookie consent requirements - GDPR/CCPA compliance affecting tracking

Why it matters:

  • Safari has ~20% browser market share (higher on mobile)
  • Firefox and Brave users are privacy-conscious and vocal
  • Inconsistent tracking skews user behavior data
  • Attribution models fail without complete data
  • Browser-specific bugs can go undetected

Common symptoms:

  • Conversion rates differ significantly by browser
  • Safari sessions appear shorter or have higher bounce rates
  • Returning visitor counts lower in Safari/Firefox
  • Cross-domain tracking fails in privacy-focused browsers
  • Third-party advertising pixels blocked

How to Diagnose

Method 1: Browser DevTools Comparison

Process:

  1. Test same user flow in multiple browsers

    • Chrome (baseline)
    • Safari (ITP)
    • Firefox (ETP)
    • Brave (aggressive blocking)
  2. Open DevTools in each browser

    // Chrome/Edge: F12 or Ctrl+Shift+I
    // Safari: Enable Develop menu → Develop → Show Web Inspector
    // Firefox: F12 or Ctrl+Shift+I
    // Brave: F12 or Ctrl+Shift+I
    
  3. Check Network tab for tracking requests

    // Look for:
    // - Google Analytics: /g/collect or /collect
    // - Facebook Pixel: facebook.com/tr
    // - Google Ads: google.com/pagead
    
    // In Safari/Firefox/Brave:
    // ❌ Requests may be blocked
    // ❌ Cookies may be restricted
    // ⚠️ Warnings about blocked content
    
  4. Check Console for errors

    // Common errors in privacy-focused browsers:
    // "Cookie blocked due to tracking protection"
    // "Third-party cookie will be blocked"
    // "Content Security Policy violation"
    

What to look for:

Browser What to Check Common Issues
Chrome Baseline - should work Rare issues
Safari Cookie restrictions, ITP warnings Short-lived cookies, blocked third-party
Firefox Tracker blocking, ETP settings Blocked known trackers
Brave Aggressive blocking Many third-party scripts blocked
Edge Similar to Chrome/Safari hybrid ITP-like behavior

Method 2: GA4 Browser Reports

Check for browser-specific anomalies:

  1. Go to GA4 Reports → Tech → Overview

  2. Look for suspicious patterns

    // Red flags:
    // - Safari bounce rate significantly higher (70% vs 40%)
    // - Safari session duration much lower (30s vs 2m)
    // - Safari conversions disproportionately low
    // - Firefox/Brave showing very few returning visitors
    
    // Example comparison:
    Browser    | Sessions | Bounce Rate | Avg Session Duration | Conversions
    Chrome     | 10,000   | 42%         | 2m 15s              | 150
    Safari     | 3,000    | 68%         | 45s                 | 15 ← Suspiciously low!
    Firefox    | 2,000    | 44%         | 2m 10s              | 30
    
  3. Segment by browser + returning visitor

    // Create segment:
    // Browser = Safari AND User type = Returning visitor
    
    // If returning visitors very low in Safari:
    // Indicates cookie lifespan issues from ITP
    

Check cookie behavior across browsers:

  1. Open DevTools → Application/Storage tab

    • Chrome/Edge: Application → Cookies
    • Safari: Storage → Cookies
    • Firefox: Storage → Cookies
  2. Compare analytics cookies

    // Look for GA4 cookies:
    _ga        // Client ID cookie
    _ga_XXXXX  // Property-specific cookie
    
    // Check:
    // - Do cookies exist in all browsers?
    // - What are expiration dates?
    // - Are cookies being set as expected?
    
    // Safari ITP may show:
    // - _ga expires in 7 days (instead of 2 years)
    // - Client-side cookies restricted
    // - Third-party cookies blocked entirely
    
  3. Test after leaving and returning

    // Test flow:
    // 1. Visit site, note Client ID
    // 2. Close browser completely
    // 3. Return next day
    // 4. Check if same Client ID
    
    // Safari ITP:
    // - Client-side set cookies may be deleted
    // - User appears as new visitor
    // - Attribution lost
    

Method 4: Third-Party Script Blocking

Test what's being blocked:

  1. Use browser's built-in tracker detection

    // Safari:
    // Settings → Privacy → Prevent Cross-Site Tracking (on by default)
    // Click shield icon in address bar to see blocked trackers
    
    // Firefox:
    // Settings → Privacy → Enhanced Tracking Protection → Strict
    // Click shield icon to see blocked content
    
    // Brave:
    // Settings → Shields
    // Default blocks ads and trackers
    
  2. Check what's blocked on your site

    • Visit your site in each browser
    • Check tracker/shield icon
    • Note which scripts are blocked
  3. Common blocked resources

    // Often blocked:
    // - Facebook Pixel (facebook.com/tr)
    // - Google Analytics (google-analytics.com)
    // - DoubleClick (doubleclick.net)
    // - AdWords conversion tracking
    // - Hotjar, Crazy Egg, other session replay tools
    

General Fixes

Fix 1: Server-Side Tracking (Most Reliable)

Goal: Bypass browser-based tracking restrictions.

Implementation:

// Instead of client-side GA4:
gtag('event', 'purchase', {...});  // Blocked by browsers

// Use Server-Side GTM:
// 1. Set up Server-Side GTM container (Google Cloud or custom server)
// 2. Route client requests to your own domain
// 3. Server forwards to GA4 Measurement Protocol

// Client sends to YOUR domain:
fetch('https://analytics.yoursite.com/collect', {
  method: 'POST',
  body: JSON.stringify({
    event: 'purchase',
    client_id: clientId,
    // ... event data
  })
});

// Your server forwards to GA4:
// Server-side code (Node.js example):
const response = await fetch(
  'https://www.google-analytics.com/mp/collect?measurement_id=G-XXXXXXX&api_secret=YOUR_SECRET',
  {
    method: 'POST',
    body: JSON.stringify({
      client_id: clientId,
      events: [{
        name: 'purchase',
        params: eventData
      }]
    })
  }
);

Advantages:

  • Works in all browsers
  • Not blocked by ad blockers
  • More accurate tracking
  • Cookie control on your domain

Disadvantages:

  • Requires server infrastructure
  • More complex setup
  • Additional costs
  • Need to manage uptime

Goal: Use cookies set by your own domain (not affected by third-party restrictions).

Implementation:

// Option 1: Server-Side Cookie Setting
// Set cookies via HTTP header (server-side)
// PHP example:
setcookie('_ga', $clientId, [
  'expires' => time() + (365 * 24 * 60 * 60), // 1 year
  'path' => '/',
  'domain' => '.yoursite.com',
  'secure' => true,
  'httponly' => false, // Need JS access for analytics
  'samesite' => 'Lax'
]);

// Option 2: Use gtag.js Cookie Settings
gtag('config', 'G-XXXXXXXXXX', {
  'cookie_flags': 'SameSite=None;Secure', // For cross-domain
  'cookie_domain': 'yoursite.com',
  'cookie_expires': 365 * 24 * 60 * 60 // 1 year in seconds
});

// Option 3: Custom Cookie Implementation
function setAnalyticsCookie(name, value) {
  const expires = new Date();
  expires.setFullYear(expires.getFullYear() + 1);

  document.cookie = name + '=' + value +
    '; expires=' + expires.toUTCString() +
    '; path=/' +
    '; domain=.yoursite.com' +
    '; SameSite=Lax' +
    '; Secure';
}

Important notes:

  • Safari ITP still limits client-side cookies to 7 days
  • Server-set cookies can last longer
  • First-party domain cookies work better than third-party

Goal: Only load tracking scripts after user consent (required for GDPR anyway).

Implementation:

// Step 1: Don't load GTM until consent given
// BEFORE (immediate load):
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXX"></script>

// AFTER (load after consent):
<script>
function loadGTM() {
  (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
  new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
  j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
  'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
  })(window,document,'script','dataLayer','GTM-XXXXX');
}

// Load GTM only after consent
if (hasAnalyticsConsent()) {
  loadGTM();
}
</script>

// Step 2: Update GTM Consent Settings
// In GTM, set default consent state:
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

// Default: deny everything
gtag('consent', 'default', {
  'analytics_storage': 'denied',
  'ad_storage': 'denied'
});

// After user accepts:
gtag('consent', 'update', {
  'analytics_storage': 'granted',
  'ad_storage': 'granted'
});
</script>

Benefits:

  • GDPR/CCPA compliant
  • Respects privacy-conscious users
  • Reduces blocking (user consented)

Fix 4: Fallback Tracking for Blocked Scripts

Goal: Detect when tracking is blocked and use fallback method.

Implementation:

// Detect if GA is blocked
function isGABlocked() {
  // Try to access GA object
  if (typeof gtag === 'undefined' && typeof ga === 'undefined') {
    return true;
  }
  return false;
}

// Use fallback if blocked
if (isGABlocked()) {
  // Fallback: Send to your own endpoint
  fetch('/api/analytics', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      event: 'page_view',
      page: window.location.pathname,
      referrer: document.referrer
    })
  });
} else {
  // Normal GA tracking
  gtag('event', 'page_view');
}

// Server-side endpoint processes and forwards to GA4

Fix 5: Test Across Browsers Regularly

Goal: Catch browser-specific issues before they impact data.

Testing protocol:

// Weekly cross-browser test checklist:
// □ Chrome (latest)
// □ Safari (latest)
// □ Firefox (latest)
// □ Brave (latest)
// □ Edge (latest)

// Test on each browser:
// 1. Clear cookies/cache
// 2. Visit homepage
// 3. Check DevTools Network tab for GA request
// 4. Perform key actions (add to cart, form submit, etc.)
// 5. Verify events in GA4 DebugView
// 6. Check for console errors
// 7. Inspect cookies

// Document results:
Browser  | Page View | Add to Cart | Purchase | Errors
---------|-----------|-------------|----------|--------
Chrome   | ✅        | ✅          | ✅       | None
Safari   | ✅        | ✅          | ❌       | Cookie blocked
Firefox  | ✅        | ✅          | ✅       | None
Brave    | ❌        | ❌          | ❌       | All blocked
Edge     | ✅        | ✅          | ✅       | None

Fix 6: Browser-Specific Workarounds

Safari ITP Workarounds:

// Issue: Safari deletes client-side cookies after 7 days (or 24 hours for bounce)

// Solution 1: Use server-side cookie setting
// Cookies set via Set-Cookie header persist longer

// Solution 2: Use localStorage + rebuild cookie
// Store Client ID in localStorage (not affected by ITP)
function getOrCreateClientId() {
  let clientId = localStorage.getItem('ga_client_id');

  if (!clientId) {
    // Create new Client ID
    clientId = 'GA1.1.' + Math.random().toString(36).substring(2) +
               '.' + Math.floor(Date.now() / 1000);
    localStorage.setItem('ga_client_id', clientId);
  }

  // Set as cookie for GA to use
  document.cookie = '_ga=' + clientId + '; max-age=63072000; path=/';

  return clientId;
}

// Use before GA loads
const clientId = getOrCreateClientId();

gtag('config', 'G-XXXXXXXXXX', {
  'client_id': clientId
});

Firefox ETP Workarounds:

// Issue: Firefox blocks known tracking domains

// Solution: Use first-party tracking
// Host analytics.js on your own domain
// Download analytics.js and serve from your server:
// https://www.google-analytics.com/analytics.js

// Serve from: https://yoursite.com/js/analytics.js
// Update GTM to load from your domain instead

Brave Browser Approach:

// Issue: Brave blocks almost everything by default

// Solution: Respect user's privacy choice
// Don't try to circumvent Brave's blocking
// Focus on server-side tracking for essential data
// Brave users chose privacy - don't break that trust

// Acceptable: Minimal server-side analytics
// Not acceptable: Fingerprinting, bypassing shields

Platform-Specific Guides

Platform Guide
Shopify Cross-Browser Testing on Shopify
WordPress Cross-Browser Testing on WordPress
Squarespace Cross-Browser Testing on Squarespace
Wix Cross-Browser Testing on Wix
Webflow Cross-Browser Testing on Webflow

Browser Privacy Feature Comparison

Feature Chrome Safari Firefox Brave Edge
Third-party cookie blocking Planned 2024 Yes (ITP) Yes (ETP) Yes Yes (TPP)
Known tracker blocking No Yes Yes Yes Yes
Cookie lifespan limits No 7 days No Yes 7 days
Fingerprinting protection Limited Yes Yes Yes Yes
Ad blocking No No Optional Yes No
Default privacy level Low Medium Medium High Medium

Best Practices

  1. Always test in Safari - It has the strictest privacy protections
  2. Consider server-side tracking - Most reliable cross-browser solution
  3. Respect privacy choices - Don't aggressively bypass privacy features
  4. Use first-party cookies - Less likely to be blocked
  5. Monitor browser-specific metrics - Watch for anomalies
  6. Implement consent management - Required anyway, helps with privacy features
  7. Document browser quirks - Keep notes on browser-specific issues

Further Reading

// SYS.FOOTER