MetrikStack
Sources

Cloudflare

Cloudflare web analytics that count cache hits and bots. Install the MetrikStack Worker on your zone in one step with a scoped API token.

The Cloudflare source is a Worker on your zone. It counts every page request that passes through Cloudflare, including cache hits your origin never sees.

It sits in front of the origin, forwards the request unchanged with fetch(request) and only reads the response. If the analytics endpoint fails, the Worker still returns the origin response, so your site keeps working.

What gets tracked

A response becomes a pageview when all of the following hold:

  • request method is GET or HEAD;
  • the response content-type contains text/html;
  • the path is not an asset: extensions .js .mjs .cjs .css .map .png .jpg .jpeg .gif .svg .ico .webp .avif .woff .woff2 .ttf .otf .eot .json .xml .txt .pdf .mp4 .webm .mp3 .wasm, or prefixes /_next/, /static/, /assets/. These are the same rules as in the Node SDK, so a URL is classified the same way whichever source sees it.

Cache HITs are tracked. An SDK on the origin never sees them, which is the main reason to run an edge source. Error pages (4xx/5xx HTML) are tracked too, with their status_code.

country is derived from ip at ingest, not sent by the Worker directly.

Request ids

For every tracked HTML response the Worker creates a UUIDv7 request_id and puts it on the response twice:

X-MetrikStack-Request-Id: 0199aa4c-…
Server-Timing: metrikstack;desc=0199aa4c-…

The browser uses the Server-Timing copy: the tracker script reads it back with performance.getEntriesByType('navigation')[0].serverTiming and sends the same id with its own event. The two are then merged into one pageview (see How merging works). The response returned to the visitor is a clone (headers on a fetch() result are immutable), so status, body and all origin headers are preserved.

Install: one-click

The dashboard can install the Worker for you with a Cloudflare API token you provide. It creates the source, uploads the Worker with its bindings and adds the route.

Create the token at My Profile → API Tokens → Create Token → Custom token with exactly these permissions, scoped to the one zone:

PermissionLevel
Zone → ZoneRead
Zone → Workers RoutesEdit
Account → Workers ScriptsEdit

Then use the Cloudflare one-click install card on the site's Sources page in the dashboard.

The token is used for that one request and never stored; only the zone id, script name and routes are kept on the source. You can revoke it in Cloudflare right afterwards and the Worker keeps running. There is no "Authorize" button because Cloudflare has no OAuth programme for third-party apps.

Installing rotates the ingest token. A new token is generated for the site's Cloudflare source and stored as the Worker secret. The previous token stops working, so any Worker you deployed earlier for this site stops sending. Otherwise you can safely reinstall on the same zone: the route is reused, and a route that belongs to a different Worker is reported back instead of overwritten.

On this page