Why is Plausible or GA4 not tracking visitors?
CSP headers blocking tracker scripts, ad-block detection, custom domain analytics setup, and script load order — fix analytics tracking on your VeloCMS blog.
You set up Plausible or GA4, waited a few days, and the dashboard is showing zero sessions — or a suspiciously low number that doesn't match reality. Analytics tracking failures have a few common causes, and most of them are fixable without touching your VeloCMS code.
Are you testing with an ad blocker installed?
Start by checking this before anything else. Open your blog in a browser with all extensions disabled (Chrome incognito mode with extensions disabled, or a fresh Firefox profile) and see if your analytics tool registers the visit. If it does, your own ad blocker is filtering out the tracking script during your testing — this is expected behavior. Your readers without ad blockers are being tracked correctly.
Studies suggest 25–40% of desktop readers use ad blockers. Plausible in particular is aggressively blocked by uBlock Origin and Privacy Badger. To track these users, Plausible offers a proxied tracker script option — serve the Plausible script from your own domain. See the Plausible docs for proxy setup.
CSP headers blocking the tracker script
VeloCMS sets a strict Content Security Policy (CSP) on all pages. The default CSP allows scripts from the page's own origin plus a few explicitly permitted CDNs. If your analytics script domain isn't in the CSP allowlist, the browser will silently block it. You'll see an error in the browser console like: 'Refused to load the script because it violates the following Content Security Policy directive: script-src...'.
To fix this, go to Admin → Settings → Advanced → Content Security Policy. Add the analytics script domain to the script-src directive. For Plausible: add plausible.io. For GA4/Google Tag Manager: add googletagmanager.com and google-analytics.com. Save and verify the error disappears in the browser console.
GA4 — real-time report lag
GA4's standard reports can have a data processing delay of up to 48 hours. Don't judge GA4 tracking by looking at the standard reports on day one. Instead, check the Realtime report in Google Analytics — it updates within seconds and is the correct way to verify if the tracking snippet is working. If you see yourself in the Realtime report when you visit your blog, GA4 is working. The standard reports will catch up.
Custom domain proxy for Plausible
If you want to reduce ad-blocker blocking, you can proxy the Plausible script through your own domain using Cloudflare Workers. The setup involves creating a Cloudflare Worker that forwards requests to plausible.io and serving the Plausible script from analytics.yourdomain.com/js/script.js instead of plausible.io/js/plausible.js. This takes about 10 minutes and significantly improves tracking completeness. See Plausible's official proxy documentation for the Cloudflare Worker script.
Script load order and timing
VeloCMS loads analytics scripts using Next.js's Script component with strategy='afterInteractive'. This means the script loads after the page is interactive — it will not block page load. If you added a custom analytics script tag directly to the theme HTML template instead of using the Admin → Settings → Analytics field, it may be blocking rendering. Use the Admin → Settings → Analytics field to add your tracking snippet — VeloCMS handles the script loading strategy automatically.
If you have both client-side and server-side analytics tracking enabled simultaneously, you may see double-counted sessions. Choose one approach: client-only (the default) or server-side-only, not both.