Install & operate
Troubleshooting
In rough order of how often each one turns out to be the cause.
No data at all
1. Check the request is being made
Open the network tab and reload. You should see v.js load, then a
POST to /api/collect returning
204. What you see instead tells you which case you are in:
| Symptom | Cause | Fix |
|---|---|---|
| No request at all | Blocker, DNT, or your own exclusion flag | See below |
404 | Wrong site id | Copy it again from the Install tab |
400 | Malformed body | Usually a hand-written event call; check the JSON |
429 | Quota exhausted | The dashboard shows the rejected count |
202 | Do Not Track | Working as intended — the event was accepted and dropped |
2. Do Not Track
We respect DNT by default. Many privacy-focused browsers send it, and you may well be using one.
For testing only, add data-do-not-track="false". In strict privacy mode
this override is disabled and cannot be re-enabled.
3. You excluded yourself
If you ever visited with ?vitrus_ignore=1, that browser is permanently
excluded. Check localStorage.getItem("vitrus.ignore") in the console, or
visit with ?vitrus_ignore=0.
4. Ad blockers
Some blockers remove analytics scripts by hostname. Try a private window with extensions disabled to confirm; if it is the cause, serve the script from your own domain.
5. The script is not on the page
Search the rendered HTML for data-site. A common cause on
platform-hosted sites is a "header code" box that only applies to some pages, or a caching layer still
serving the previous build.
6. A skip pattern matches
If data-skip-patterns is set, check it against the page you are testing.
/** anywhere in the list disables the whole site.
Numbers look wrong
"2 visitors, 1 pageview"
A dual-stack browser can reach the site over IPv4 on one request and IPv6 on the next. The two addresses have nothing in common and cannot be joined without a stored identifier. Rare, but real — see the privacy notes.
Every visitor is the same person
Almost always a proxy that is not forwarding the client IP, so everyone hashes identically. Make
sure X-Forwarded-For reaches us.
Bounce rate is far too high
Bounce means "one pageview in the session". A blog where people read one article and leave will have a high bounce rate and nothing is wrong. See how we count.
The country table is empty
Country comes only from a proxy header (Cloudflare, Vercel, Fly, CloudFront, Netlify). Without one, the table stays empty and says so — we do not ship a GeoIP database, and we will not guess.
The number does not match GA4
It will not, and neither tool is broken. GA4 filters bots differently, defines sessions differently, and samples above a threshold. Click the number in Vitrus, read the query, and check whether the definition is the one you wanted — that is what the evidence panel is for.
SPA routes are not counted
The tracker patches pushState and
replaceState. If your router changes the URL some other way, or you set
data-auto="false", call vitrus("pageview")
after navigation yourself.
Still stuck
Email [email protected] with your site id, the URL you are testing and what the network tab shows. If you self-host, the server logs the rejection reason for every non-2xx response.