Article Information
Category: Analytics
Published: 11 March, 2026
Author: Chris de Gruijter
Reading Time: 9 min
Tags

Cookieless Analytics: How I Built a Self-Hosted Tracking Script That Doesn't Need Consent Banners
Published: 11 March, 2026
Every website needs analytics. But since GDPR, ePrivacy, and a dozen other privacy regulations landed, the simple act of tracking pageviews has become a legal minefield. Install Google Analytics? You need a cookie consent banner. Use a third-party script? You're sharing visitor data with an American company. Skip analytics entirely? You're flying blind.
I wanted a middle ground: real analytics data — pageviews, referrers, device breakdowns, top pages — without cookies, without consent banners, and without sending visitor data to third parties. So I built my own tracking script. Here's how it works and why it matters.
The Problem with Google Analytics in 2026
Google Analytics 4 is powerful, but it comes with serious baggage for European websites:
- Cookies — GA4 sets cookies by default, which triggers GDPR consent requirements
- Data transfer — visitor data is processed on Google's US-based servers, raising Schrems II compliance questions
- Consent banners — if visitors decline cookies (and many do), you lose that data entirely
- Script weight — the gtag.js script adds 28-45KB to every page load
- Data sampling — on the free tier, GA4 samples data for high-traffic properties
For my client websites — Dutch construction companies that get 500-2,000 visits per month — Google Analytics is overkill. I don't need funnel analysis or predictive audiences. I need to know which pages get traffic, where visitors come from, and what devices they use. That's it.
The Architecture: What I Built
The system has three parts: a lightweight tracking script that runs on client websites, a collector API that receives and stores events, and a dashboard UI that visualizes the data.
1. The Tracking Script (~2KB)
The tracking script is a tiny JavaScript snippet that fires on every page load. It collects:
- Page URL and title — what the visitor is looking at
- Referrer — where they came from (Google, social, direct, etc.)
- Screen resolution and viewport — desktop vs mobile detection
- User agent — browser and OS identification
- Timestamp — when the visit happened
- Session ID — a random ID generated per browser tab (not persisted, no cookies)
Crucially, it does not collect: IP addresses (hashed or otherwise), cross-site identifiers, persistent user IDs, or any data that could identify a specific person. The session ID is generated fresh on every page load using crypto.randomUUID() — it's useful for counting sessions but can't track a user across visits.
2. The Collector API
The tracking script sends a POST request to a collector endpoint. This is a simple API route in the dashboard application that validates the payload and inserts it into a Supabase table. The collector:
- Validates the
client_idagainst known clients - Strips any accidental PII from the payload
- Normalizes the user agent into device type, browser, and OS fields
- Stores the event in an
analytics.pageviewstable - Returns a 204 No Content (the script doesn't wait for a response)
3. The Dashboard
The analytics section in the marketing dashboard shows the data I actually care about:
- Traffic over time — daily/weekly/monthly pageview trends
- Top pages — which pages get the most visits
- Referrers — Google organic, direct, social, and specific referral sources
- Devices — desktop vs mobile vs tablet split
- Browsers and OS — Chrome, Safari, Firefox breakdown
- Geo (country-level) — derived from Accept-Language header, not IP geolocation
Why No Cookies Means No Consent Banner
Under GDPR and the ePrivacy Directive, consent banners are required when you store or access information on a user's device — i.e., cookies. If your analytics solution doesn't set cookies, doesn't use localStorage, and doesn't fingerprint the device, there's no "storage" happening on the user's device, and no consent is required for analytics purposes.
This is the same legal basis that tools like Plausible, Fathom, and Simple Analytics rely on. The key is that the data collected must be genuinely anonymous — you can't identify or re-identify a specific person from the data you store. By using random session IDs that aren't persisted and not collecting IP addresses, my tracker meets this threshold.
Important caveat: I'm not a lawyer. If you're operating in a regulated industry or handling sensitive data, consult a privacy professional. For standard business websites in the Netherlands, this approach is widely accepted.
Implementation Details
The Tracking Script
The script is intentionally minimal. It runs after the page loads, collects the data points listed above, and sends a single POST request using navigator.sendBeacon() (which doesn't block page unload) or falls back to fetch(). The entire script is under 2KB minified — compared to 28-45KB for Google Analytics.
// Simplified version of the tracking script
(function() {
const endpoint = 'https://dashboard.webfluentia.agency/api/analytics/collect';
const data = {
client_id: 'your-client-id',
url: window.location.href,
title: document.title,
referrer: document.referrer || null,
screen: screen.width + 'x' + screen.height,
viewport: window.innerWidth + 'x' + window.innerHeight,
ua: navigator.userAgent,
ts: new Date().toISOString(),
sid: crypto.randomUUID(),
};
navigator.sendBeacon(endpoint, JSON.stringify(data));
})();Deploying the Script
The script is deployed as a static file on each client's website and loaded with a <script> tag in the page footer. No npm packages, no build step, no dependencies. For Nuxt sites, I add it as a plugin. For Next.js sites, it goes in the root layout. For static sites, a simple <script src> tag.
Comparison: Self-Hosted vs Google Analytics vs Plausible
Here's how the three approaches compare for a small business website:
- Google Analytics (free): Full-featured but requires consent banner. 28-45KB script. Data processed in US. Risk of data sampling. Free but you pay with user data.
- Plausible ($9/month): Cookie-free, privacy-friendly. ~1KB script. EU-hosted. No consent banner needed. Limited customization.
- Self-hosted (included in dashboard): Cookie-free, no third-party data sharing. ~2KB script. Data stays in your own Supabase instance. Fully customizable. $0 extra cost if you already have the dashboard.
For my use case — three client websites already using the Webfluentia dashboard — self-hosting was the obvious choice. Zero additional cost, complete data ownership, and I can customize the metrics to match exactly what I need.
What I'd Do Differently
- Add event tracking from day one — I initially only tracked pageviews. Adding button clicks, form submissions, and scroll depth later required changes to both the script and the database schema.
- Use a dedicated analytics schema — I put analytics tables in the main schema initially. Moving them to a dedicated
analyticsschema later caused some migration headaches. - Batch events — The script currently fires one request per pageview. For high-traffic sites, batching events (e.g., every 5 seconds) would reduce the number of API calls significantly.
Conclusion
You don't need Google Analytics to understand your website traffic. A lightweight, cookie-free tracking script gives you the metrics that actually matter — pageviews, referrers, devices, top pages — without the legal overhead of consent banners or the privacy concerns of third-party data processing.
If you're already running a dashboard or have a Supabase instance, building your own analytics tracker is a weekend project that eliminates a monthly SaaS cost and gives you complete control over your data. For client websites that don't need enterprise analytics, it's the pragmatic choice.
Frequently Asked Questions
Is cookieless analytics really GDPR compliant?
If your analytics solution doesn't set cookies, doesn't use localStorage, doesn't fingerprint devices, and doesn't collect personally identifiable information, it generally falls outside the scope of cookie consent requirements under GDPR and ePrivacy. However, you still need to mention data collection in your privacy policy. Consult a privacy professional for your specific situation.
Can you track unique visitors without cookies?
Not precisely. Without persistent identifiers, you can't distinguish a returning visitor from a new one. You can count sessions (each page load gets a random session ID) and pageviews, but "unique visitors" in the GA4 sense isn't possible without cookies or fingerprinting. For most small business websites, session and pageview counts are sufficient.
Why not just use Plausible or Fathom?
Plausible and Fathom are excellent services. If you don't have an existing dashboard or database, they're the easiest cookie-free analytics option. I built my own because I already had the infrastructure (Supabase, dashboard app) and wanted zero additional monthly cost for three client sites.
How accurate is cookieless analytics compared to Google Analytics?
For pageviews and session counts, very accurate — arguably more accurate than GA4, because you capture data from visitors who decline cookie consent. For user-level metrics (returning visitors, user journeys, cohort analysis), cookieless analytics is less capable. It's a trade-off: broader coverage of basic metrics vs deeper insights for consenting users.