# Supported runtimes and coverage limits

> What each Virent installation observes on browser-only sites, Next.js, Node.js servers and edge runtimes, and the collection controls that apply.

Canonical: https://virent.app/docs/installation/runtimes-and-coverage
Last updated: 2026-10-10

One website keeps one `websiteId`, one publishable browser key and one server
secret. Browser and crawler collection are separate channels and are validated
independently. The workspace installation status reports per channel: health
(`receiving`, `waiting`, `stale`, `disconnected`, `unsupported`,
`unavailable`), the last accepted event, when the channel was last validated,
and the SDK adapter, version and runtime that last reported on that channel.

The [framework guides](/docs#installation) give copy-paste steps. This page states
what each setup can and cannot observe.

## Recipes by runtime

| Runtime | Install | Observes | Does not observe |
|---|---|---|---|
| Browser-only or static site | Hosted script (`/js/script.js`) or `@virent.app/sdk/browser` | Pageviews, custom events, referrers and campaign attribution, identity links, goals | Crawler requests that do not run JavaScript. Sites without server code need provider logs for crawler coverage. |
| Next.js on Node.js (`proxy.ts`) | Browser script plus `createVirentBotProxy` from `@virent.app/sdk/next`; optional first-party route with `createVirentAnalyticsProxy` | Browser events and crawler requests that reach the proxy | Final response status (the proxy runs before rendering). Requests answered by a CDN cache never reach the proxy. Still two channels and two keys. |
| Express or other Node.js SSR | Browser script in the shared layout plus request middleware (the guide's handler, or `createVirentBotTracker` from `@virent.app/sdk/server` with a Fetch `Request`) | Browser events and crawler requests handled by that Node.js process | Requests served by a CDN or static host in front of the app. The middleware must run at the layer that serves pages. |
| Cloudflare Workers and other edge isolates | Browser script plus verified provider logs for crawlers | Browser events; crawler requests as reported by the provider log integration | The Node.js crawler adapter is not an edge adapter. A crawler report from an edge runtime marks the crawler channel `unsupported`. |

[Hosting integrations](/docs/integrations/overview) (Vercel, Cloudflare, AWS
CloudFront, Akamai, Netlify, Google Cloud, Fastly, Framer, Webflow) remain
available. Their presence is not a certification of
every plan or deployment configuration.

## Collection controls

- **Consent.** Start consent-managed installs with `consent: "pending"` (SDK) or
  `data-consent="pending"` (hosted script). While pending, nothing is stored or
  sent. Up to five pageviews requested while pending are held in memory and
  sent once consent is granted; they are discarded on denial or page unload.
  Custom events, identity links and goals are never held.
- **Do Not Track.** Opt-in. Set `respectDoNotTrack: true` (SDK) or
  `data-respect-do-not-track="true"` (hosted script) to stop collection when the
  browser sends DNT. Installations that do not set it keep their current
  behavior.
- **Pause and resume.** `pause()` / `window.virent("pause")` stop subsequent
  tracking until `resume()`; they do not override consent or DNT.
- **Repeated initialization.** `initVirent` with equivalent options reuses the
  active client and sends no second automatic pageview. Plain values compare by
  value; functions and objects such as `fetch` or storage compare by identity.
  Different options replace the client and log a console warning.
- First-party forwarding (a `/_vr` relay or `createVirentAnalyticsProxy`)
  relays the same events, so the same controls apply. See "First-party
  (recommended)" in your framework guide.

## Secret boundary

`@virent.app/sdk/server` and `@virent.app/sdk/next` take the server secret.
From SDK 0.4.0 their `browser` export condition resolves to a module that throws,
so a client bundle that imports them fails instead of shipping the secret.
Client code imports `@virent.app/sdk/browser`. Keep `VIRENT_INGEST_SECRET` in
server environment variables only.

## Adapter reporting

Browser adapters add `sdk: { adapter, version }` to the ingest body; server
adapters send `x-virent-sdk: <adapter>/<version>; runtime=<node|edge|unknown>`.
Both are optional and ignored by older servers. Ingest logs the adapter and
version, and the installation status shows the last report per channel. The
report is diagnostic and never changes whether an event is accepted.
