Cloudflare
Edge source for Cloudflare zones: one-click install and what gets tracked.
The Cloudflare source is a Worker on your zone.
It sits in front of the origin, forwards the request unchanged with
fetch(request), and only observes the response. A broken analytics
endpoint can never take the site down, because every failure path returns
the origin response.
What gets tracked
A response becomes a pageview when all of the following hold:
- request method is
GETorHEAD; - the response
content-typecontainstext/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 filter rules as the Node SDK, so a URL is classified the same way whichever source sees it.
Cache HITs are tracked. They're exactly the pageviews an origin-side SDK
never sees, which is the reason to run an edge source at all. 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.
The request-id merge story
For every tracked HTML response the edge mints a UUIDv7 request_id and puts
it on the response twice:
X-MetrikStack-Request-Id: 0199aa4c-…
Server-Timing: metrikstack;desc=0199aa4c-…The Server-Timing copy is the one that matters in a browser: 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 and the CLI can do the whole Worker install for you (create the source, upload the Worker with its bindings, and add the route) from a Cloudflare API token you supply.
Create the token at My Profile → API Tokens → Create Token → Custom token with exactly these permissions, scoped to the one zone:
| Permission | Level |
|---|---|
| Zone → Zone | Read |
| Zone → Workers Routes | Edit |
| Account → Workers Scripts | Edit |
Then either open Site → Sources → Connect Cloudflare in the dashboard, or:
metrikstack setup cloudflare --site example.com --token <cf-token>
# or: export CLOUDFLARE_API_TOKEN=… && metrikstack setup cloudflare --site example.comThe token is used for that one request and is never stored; only the zone id, script name and routes are kept on the source. You can revoke it in Cloudflare straight afterwards; the deployed Worker keeps running. Cloudflare has no third-party OAuth app programme, which is why there is no "Authorize" button here.
Installing rotates the ingest token. A fresh token is generated for the site's Cloudflare source and written into the Worker secret. The previous token stops being accepted, so any Worker you deployed earlier for this site stops sending. Reinstalling over the same zone is otherwise fine: the route is reused, and a route already owned by a different Worker is reported back instead of overwritten.