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:

SymptomCauseFix
No request at allBlocker, DNT, or your own exclusion flagSee below
404Wrong site idCopy it again from the Install tab
400Malformed bodyUsually a hand-written event call; check the JSON
429Quota exhaustedThe dashboard shows the rejected count
202Do Not TrackWorking 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.