How We Set Up Google Analytics for Privacy-First Tracking

A complete guide to implementing Google Analytics with Content Security Policy, privacy considerations, and dual tracking with Plausible Analytics.

The Dilemma: Insights vs Privacy

We wanted analytics on Neorgon to understand which tools people use, but we didn't want to sacrifice privacy. The obvious choice was a privacy-first solution like Plausible, but we also wanted to experiment with Google Analytics 4 to compare data models.

So we implemented bothβ€”and learned how to do it responsibly.

πŸ’‘ Our Analytics Stack

  • Plausible Analytics - Primary, privacy-first, GDPR-compliant
  • Google Analytics 4 - Secondary, for experimentation and comparison
  • No cookies - Both use anonymized tracking
  • Content Security Policy - Locked down to prevent data leakage

Step 1: Basic Google Analytics Setup

Adding GA4 is straightforward. You need two scripts in your <head>:

head (immediately after charset meta)
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-HTF349S8R5"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-HTF349S8R5');
</script>

The first script loads the library. The second initializes tracking. Replace G-HTF349S8R5 with your Measurement ID from Google Analytics.

Step 2: Content Security Policy Configuration

This is where most people mess up. GA requires specific CSP directives to work:

meta http-equiv="Content-Security-Policy"
<meta http-equiv="Content-Security-Policy"
      content="
        default-src 'self';
        script-src 'self' 'unsafe-inline'
          https://www.googletagmanager.com
          https://www.google-analytics.com;
        img-src 'self' data:
          https://www.google-analytics.com
          https://www.googletagmanager.com;
        connect-src https://www.google-analytics.com
                   https://www.googletagmanager.com
      ">

What Each Directive Does:

  • script-src - Allows GA's JavaScript to load and execute
  • img-src - GA uses pixel images for tracking
  • connect-src - Required for event collection API calls
  • 'unsafe-inline' - GA uses inline scripts (unavoidable)

⚠️ Security Warning

We use 'unsafe-inline' because GA requires it. To mitigate risk:

  • Keep GA script in <head> (immediately after meta tags)
  • Restrict other inline scripts to non-GA pages
  • Use CSP nonces for other inline scripts if needed

Step 3: Dual Tracking with Plausible

Plausible is our primary analytics. It's lightweight, open-source, and GDPR-compliant:

head (after GA)
<!-- Privacy-first analytics -->
<script defer data-domain="neorgon.com"
        src="https://plausible.io/js/script.js"></script>

Key differences from GA:

  • defer attribute - Loads after page render (non-blocking)
  • data-domain - Your domain, auto-detected
  • No cookies - Uses localStorage, not cookies
  • 1KB script vs GA's 50KB+

Step 4: Testing Your Setup

1. Check Browser Console

Open DevTools β†’ Console. Look for:

  • βœ… No CSP violations
  • βœ… GA library loads (no 404s)
  • βœ… Plausible script loads

2. Verify Network Requests

DevTools β†’ Network tab:

  • Filter: google-analytics - Should see collect?v=2... requests
  • Filter: plausible - Should see api/event requests
  • Both should return HTTP 200

3. Check Analytics Dashboards

  • Plausible: Real-time tab shows immediate visits
  • GA4: Reports β†’ Realtime (updates every few seconds)

Privacy Considerations

What We Track (And Don't)

Tracked
  • βœ“ Page views and unique visitors
  • βœ“ Referrer sources (where users come from)
  • βœ“ Device type (mobile/desktop)
  • βœ“ Geographic region (country/city)
  • βœ“ Tool usage patterns (which cards get clicked)
Not Tracked
  • βœ— Individual IP addresses (anonymized)
  • βœ— Personal data or form inputs
  • βœ— Cross-site tracking
  • βœ— Individual user profiles
  • βœ— Demographic data

GDPR Compliance Checklist

  • βœ… No cookies - Both trackers are cookie-less
  • βœ… Anonymized IPs - GA4 auto-anonymizes last octet
  • βœ… No personal data - We don't ask for it
  • βœ… Transparent - This blog post is our privacy policy
  • βœ… Opt-out - Users can block scripts with ad blockers

Comparing The Data Models

After running both for a week, here's what we learned:

Plausible (Privacy-First)
  • βœ… Immediate real-time data
  • βœ… Simple, focused dashboard
  • βœ… Open source (can self-host)
  • βœ… No data sampling
  • ⚠️ Limited historical analysis
Google Analytics 4
  • βœ… Powerful segmentation and funnels
  • βœ… Integration with Google Ads
  • βœ… Advanced attribution modeling
  • βœ… Free for most use cases
  • ⚠️ Complex UI, steep learning curve
  • ⚠️ Data sampling on high traffic

Troubleshooting Common Issues

Issue: CSP Violations

Error: Refused to load the script...

Fix: Add all GA domains to your CSP directives

Issue: No Data in GA

Check: Measurement ID is correct, no ad blocker, CSP allows images

Debug: Use GA Debugger Chrome extension

Issue: Data Discrepancy Between Plausible and GA

Normal: Different tracking methodologies, expect 10-20% variance

Plausible: Counts unique visitors more conservatively

GA: Uses sessions and engaged sessions

Our Recommendation

For most projects: Use Plausible only.

It's simpler, privacy-respecting, and gives you 90% of what you need.


For complex funnels/attribution: Use GA4 + Plausible.

Plausible for day-to-day, GA4 for deep analysis when needed.

Further Reading