What is reported#

Only crawler page hits are sent. Assets, API calls and ordinary browser traffic never leave your server, so reporting stays tiny even on a busy site.

The rules#

A request is reported only when all of these hold:

  1. Method is GET or HEAD.
  2. Path is page-like: an HTML document, or robots.txt, llms.txt, llms-full.txt or a sitemap file (*sitemap*.xml, .xml.gz). Paths whose last segment has a known asset extension (.js, .css, .png, .json, .pdf, ...) are skipped, while paths that merely contain a dot (/user/john.doe) still count. /api, /graphql, /_next/, health endpoints (/health, /healthz, /livez, /readyz, /ping) and your ignorePaths are skipped.
  3. Response is HTML, when the content type is known. Crawler files and redirects (3xx) count whatever their content type.
  4. User agent looks automated: not starting with Mozilla/ (command-line tools and HTTP libraries), or carrying a crawler token (bot, crawler, spider, preview and fetcher names, headless browsers, a +http contact URL), or a browser user agent that contradicts itself in a way no shipped browser does (the legacy Edge/ token beside Chrome 79 or later, an iOS hardware model such as iPhone13,2 where iOS puts the platform, or a Safari Version/ newer than the iOS carrying it). Requests without a user agent are not reported, since REVU classifies each hit by it. Health-check probes (kube-probe, ELB-HealthChecker, GoogleHC, Consul Health Check, Envoy/HC) are never reported.

Examples#

RequestReportedWhy
GET /pricing from curl/8.7.1, HTMLyesa scripted client fetching a page
GET /pricing from a crawler with a +https://... contact URLyesa crawler token in a browser-like user agent
GET /pricing from a Safari user agent newer than its iOSyesa browser user agent no browser sends
GET /robots.txt from a crawler, plain textyescrawler files count whatever their content type
GET /old-page answered with a 301yesredirects count whatever their content type
GET /pricing from a desktop browsernoordinary browser traffic
GET /app.js from a crawlernoa static asset
GET /api/users from a crawlernoa built-in ignore
POST /contact from a crawlernonot GET or HEAD
GET / from kube-probe/1.29noa health-check probe
GET /healthz from a monitornoa health endpoint
GET /pricing with no user agentnoREVU cannot classify it

A pre-filter, not the verdict#

Rule 4 is a cheap pre-filter. It is generous on purpose, and its only guarantee is that ordinary browser traffic is never sent. REVU re-classifies every hit it receives and drops the ones it does not recognize as automated, so a hit that passes the pre-filter is not necessarily stored.

Skipping your own paths#

Add prefixes or regular expressions to ignorePaths for pages that should never be reported, such as an admin area or preview routes:

const revu = createRevuServer({
  serverKey: process.env.REVU_SERVER_KEY,
  ignorePaths: ["/admin", /^\/preview\//],
});

The built-in ignores (/api, /graphql, /_next/ and the health endpoints /health, /healthz, /livez, /readyz, /ping) always apply.

For a rule the path cannot express, such as a staff header, a preview host or a known internal address, add shouldReport. It runs last, only for hits that would otherwise be sent, and gets the same request track() got. Return false to drop the hit:

const revu = createRevuServer({
  serverKey: process.env.REVU_SERVER_KEY,
  shouldReport: (request) => request.remoteAddress !== "10.0.0.5", // your own monitor
});

Keep it synchronous and cheap, since it runs on the request path. A check that throws drops the hit. For skipping requests that bypassed your CDN, see Requests that bypass your edge.