Install & operate

Serving from your own domain

Some content blockers remove third-party analytics scripts by hostname. Serving the script and the ingest endpoint from your own domain makes them first-party requests, and typically recovers the 10–30% of visitors that would otherwise be invisible.

This is not evasion. Do Not Track is still respected, no cookie is set and no identifier is stored. A proxy changes where the request goes, not what is collected. If a visitor sends DNT, they are still not measured.

What you need to proxy

Your pathUpstreamWhy
/vs.jshttps://app.vitrus.dev/v.jsThe tracker script
/vs/api/collecthttps://app.vitrus.dev/api/collectWhere events are sent

Pick your own path names — /vs.js is just an example. Then point the tag at them with data-host:

<script defer data-site="SITE_ID"
        data-host="https://example.com/vs"
        src="/vs.js"></script>

data-host is the base the tracker appends /api/collect to, which is why the example above proxies /vs/api/collect.

nginx

location = /vs.js {
    proxy_pass https://app.vitrus.dev/v.js;
    proxy_set_header Host app.vitrus.dev;
    proxy_ssl_server_name on;
}

location /vs/api/collect {
    proxy_pass https://app.vitrus.dev/api/collect;
    proxy_set_header Host app.vitrus.dev;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_ssl_server_name on;
}
X-Forwarded-For matters. Without it every visitor arrives with your server's IP, they all hash to the same visitor id, and your unique count collapses to roughly one.

Caddy

example.com {
    handle /vs.js {
        rewrite * /v.js
        reverse_proxy https://app.vitrus.dev {
            header_up Host app.vitrus.dev
        }
    }
    handle /vs/api/collect {
        rewrite * /api/collect
        reverse_proxy https://app.vitrus.dev {
            header_up Host app.vitrus.dev
        }
    }
}

Next.js

// next.config.js
module.exports = {
  async rewrites() {
    return [
      { source: "/vs.js", destination: "https://app.vitrus.dev/v.js" },
      { source: "/vs/api/collect", destination: "https://app.vitrus.dev/api/collect" }
    ];
  }
};

Vercel

// vercel.json
{
  "rewrites": [
    { "source": "/vs.js", "destination": "https://app.vitrus.dev/v.js" },
    { "source": "/vs/api/collect", "destination": "https://app.vitrus.dev/api/collect" }
  ]
}

Cloudflare Workers

export default {
  async fetch(request) {
    const url = new URL(request.url);
    const target = url.pathname === "/vs.js"
      ? "https://app.vitrus.dev/v.js"
      : "https://app.vitrus.dev/api/collect";
    return fetch(target, request);
  }
};

Checking it worked

  1. Load your site and confirm /vs.js returns JavaScript, not a 404.
  2. In the network tab, the collect request should go to your own domain and return 204.
  3. In the dashboard, check that unique visitors is not stuck at 1 — if it is, the forwarded IP header is missing.

Self-hosting instead

If you self-host, this is moot: the script and the endpoint are already on your own domain. See self-hosting.