Count blocked visitors

Serve the tracker from your own domain so ad blockers stop hiding part of your traffic: a custom tracking domain, a reverse proxy, or the WordPress plugin's built-in proxy.

Ad blockers and privacy extensions work from filter lists of known analytics domains. When a visitor runs one, the request to Numative is blocked before it leaves the browser. The visit happens and is never recorded. Depending on your audience, that share is commonly between 10% and 40%. Technical and privacy-conscious audiences sit at the high end.

The fix is to serve tracking from your own domain, so the requests look like your site talking to itself. Numative supports three ways to do this. All of them use a per-site random path for the script, so no filter list can name it.

How it works

  • The tracker script is served from your domain at /<slug>.js, where the slug is random and unique to your site.
  • Events still go to Numative directly first, because that gives the best data: our platform sees the visitor's real IP and location. When that request is blocked, the tracker retries through your domain and keeps using it for the rest of the page. Unblocked visitors never take the detour.
  • Your proxy forwards the visitor's IP under a per-site secret, so Numative counts the real visitor rather than your server. Without the secret, a public endpoint that trusted forwarded IPs would let anyone forge visitor identity.

WordPress: nothing to do

The WordPress plugin (4.5.0 and later) does all of this automatically once your ingest key is connected. It serves the script from your site, relays blocked events, and falls back to standard tracking on its own if your server cannot reach Numative. There is a toggle under Numative > Settings > Features if you want it off.

Custom tracking domain: one DNS record

Works on any platform, including hosted ones like Shopify, Squarespace, Wix and Webflow, because it needs no server changes at all.

  1. 1

    Pick a subdomain

    In your site's Settings > Count blocked visitors, enter a subdomain of your own domain, such as stats.example.com, and press Connect.
  2. 2

    Add the CNAME record

    At your DNS provider, create the CNAME record the card shows. If your DNS is on Cloudflare, set the record to DNS only (grey cloud); proxying it breaks certificate issuance.
  3. 3

    Wait for the green check

    The card polls DNS automatically. Propagation usually takes minutes, occasionally up to a day. The certificate is issued automatically.
  4. 4

    Switch your snippet

    Once verified, the card shows your new snippet. It is the same tracker, served from your subdomain, and events report to the subdomain too. Replace the old tag with it.

Because the platform still terminates these requests, visitor IPs and locations stay fully accurate on this route. No secret and no forwarding are involved.

  • SEO: the subdomain serves only the tracker; any other URL on it redirects to your own site, so nothing new exists for search engines to index. Your pages, rankings and links are untouched.
  • Security: the subdomain grants nothing the snippet did not already have; a script tag on your pages already runs in your site's context. The tracker still sets no cookies. One rule to follow: if you ever remove the tracking domain, delete the CNAME record too. A record left pointing at a detached hostname is the textbook setup for a subdomain takeover.
  • CSP: if your site sends a Content-Security-Policy, allow the tracking domain in script-src and connect-src.
  • CAA: if your DNS has CAA records, they must permit Let's Encrypt (letsencrypt.org) or certificate issuance for the subdomain will fail. Most domains have no CAA records and need nothing.

Reverse proxy: for your own server or edge

If you deploy your own site, you can proxy the script and the collector through your origin. Settings > Count blocked visitors generates paste-ready configs with your slug and secret filled in for Next.js middleware, Netlify Edge Functions, Cloudflare Workers, nginx and Apache, plus the matching snippet:

html
<script
  defer
  src="/YOUR_SLUG.js"
  data-site="YOUR_SITE_ID"
  data-api="https://app.numative.com/api/event"
  data-fallback="/YOUR_SLUG/api/event"
></script>

data-api is the direct collector (primary); data-fallback is your proxied path, used only when the direct request fails at the network level.

Writing your own proxy

Any proxy works if it does two things: serve https://app.numative.com/<slug>.js at /<slug>.js, and forward POSTs from /<slug>/api/{event, errors, vitals, page-signal} to the same paths under https://app.numative.com/api/, passing the original request headers through and adding these:

HeaderValueRequired
X-Numative-Proxy-SecretThe per-site secret from the settings card or /api/v1/proxy-config.Yes
X-Numative-Client-IpThe visitor's IP as your server saw it.Yes
X-Numative-CountryISO 3166-1 alpha-2 country code, if your platform knows it.No
X-Numative-RegionRegion code, if known.No
X-Numative-CityCity name, URI-encoded, if known.No

Forwarding the original User-Agent and Sec-CH-UA headers matters: bot classification reads both, and a proxy that strips them degrades it. DNT and Sec-GPC must survive the relay too, or the site's "respect Do Not Track" setting cannot see the signal.

What to expect in the data

  • Visitor counts become complete. Sites with technical audiences often see totals rise noticeably once a proxy is on. That is not inflation; it is traffic that was always there.
  • Locations stay exact on the custom-domain route. On relayed routes, locations are exact where the proxy platform provides them (Cloudflare, Vercel, Netlify) and recorded as unknown where it cannot (nginx, Apache, most WordPress hosts). Unknown is deliberate: the alternative is recording every blocked visitor at your server's location.
  • Privacy behavior is unchanged. Still no cookies, no persistent identifiers, and Do Not Track and Global Privacy Control are honored exactly as before. The proxy changes which path a request takes, not what is collected.
No proxy defeats every blocker. A few block by URL patterns or heuristics rather than domain lists, and a visitor who disables JavaScript sends nothing at all. First-party serving closes most of the gap, not all of it.