@nais/apm API reference

@nais/apm wraps @grafana/faro-web-sdk with an ergonomic, capture-oriented API. This page documents the public API of version 0.1.0. For installation, see Track frontend errors with @nais/apm.

Pre-1.0

The public API may change across 0.x minor releases (new options, renamed fields, new exports such as tracing and React helpers). Pin an exact version and read the CHANGELOG before upgrading.

init(options?)

Initializes the SDK. Safe to call once — a second call warns and returns the existing instance. Returns the underlying Faro instance.

ts

InitOptions

All fields are optional. app, version, environment, and telemetryUrl each resolve independently (see Configuration resolution).

OptionTypeDescription
appstringApplication name.
versionstringApp version / release. Used for grouping and release tagging; also set as Faro release.
environmentstringEnvironment, e.g. prod-gcp.
telemetryUrlstringCollector URL.
beforeSend(item) => item | nullRuns before the mandatory PII scrubber. Return null to drop the item.
ignoreErrorsPatternsExtra patterns appended to DEFAULT_IGNORE_ERRORS.
dangerouslyDisablePiiScrubbingbooleanDisables built-in PII scrubbing. See Privacy. Default false.
faroPartial<BrowserConfig>Escape hatch: raw Faro overrides, merged last (except beforeSend, which stays composed with the scrubber).
sessionReplayobjectOpt-in session replay. See sessionReplay below.
screenshotOnErrorbooleanOpt-in masked DOM snapshot per new error. Off by default; auto-disabled when sessionReplay is enabled.

sessionReplay fields: enabled (boolean), mode ('on-error' default, or 'always'), sampleRate (0..1, default 1), block (string[], tighten-only). See Enable session replay.

ts

Configuration resolution

Each of app, version, environment, and telemetryUrl resolves independently, highest priority first:

  1. Explicit init() options.
  2. Nais meta tags in the served HTML:
    html
  3. Build-time environment variablesNAIS_APP_NAME, NAIS_CLUSTER_NAME, and a version derived from NAIS_APP_IMAGE's tag (or GITHUB_SHA). These only work when your bundler inlines process.env.* (webpack DefinePlugin, Vite define, Next.js env).
  4. Collector fallback — with no explicit or meta collector URL, well-known Nais collectors are derived from the cluster name (prod-* and dev-*).
  5. Dev mode — if no collector URL resolves at all (typically localhost), nothing is sent; every signal is echoed to the console instead.

captureException(error, options?)

Captures an exception. No event ID is returned (a Faro limitation).

ts

CaptureExceptionOptions: context? (Record<string, unknown>) and fingerprint? (string, a custom grouping key).

ts

captureMessage(message, level?)

ts

SeverityLevel is 'fatal' | 'error' | 'warning' | 'log' | 'info' | 'debug'.

ts

setUser(user) / clearUser()

ts

User: { id?, email?, username? }. Set a hashed subject as id where you can.

ts

setTag(key, value)

Attaches a single key/value tag. Faro has no first-class tag concept, so the value rides along as context on every subsequent capture rather than as an indexed label.

ts

setContext(name, context)

Attaches named context, flattened as name.key, to every subsequent capture. Pass null to remove a previously set context.

ts

captureFeedback(message, options?)

Free-text user feedback capture.

Not yet available — internal pilot only

User feedback is not part of the supported Nais APM feature set yet. Free text flows into Loki, which is shared across all teams and must never contain personal information, so this is limited to internal applications during an internal pilot. If you wire it up, your feedback UI must warn users not to enter any personal information (names, fødselsnummer, contact details, case details). Do not use it on citizen-facing apps.

ts

CaptureFeedbackOptions: category? ('bug' | 'idea' | 'other', default 'other'), email? (only sent when email-shaped), fingerprint? (joins to an issue), context? (Record<string, string>, scrubbed like the message). The message is scrubbed, trimmed, and capped at 4000 characters; empty messages are dropped.

isInitialized()

ts
ts

scrubString(value)

Exposes the PII scrubber directly, e.g. to sanitize a string before you log it yourself.

ts
ts

Privacy: PII scrubbing

Every outgoing signal — exception values, stack traces, log lines, context values, and the page URL — passes through a beforeSend scrubbing pipeline before it leaves the browser:

  • Norwegian fødselsnummer (11 digits, date-prefix sanity-checked, including D-numbers, H-numbers, and synthetic test numbers) → [fnr]
  • Email addresses[email]
  • Token-bearing URL parameters (token, access_token, id_token, refresh_token, code, state) → [redacted]

Your own init({ beforeSend }) runs first and may drop items by returning null; the scrubber always runs last, so it also sees anything your hook added. Opting out requires an explicit init({ dangerouslyDisablePiiScrubbing: true }) — and then your team owns the GDPR consequences of everything the app sends. Scrubbing is regex-based and best-effort — a safety net, not a GDPR guarantee. Don't put personal data in error messages in the first place.

Local development

On localhost (or anywhere no collector URL resolves), init() warns once, sends nothing over the network, and echoes every signal to the console. Calling any capture function before init() is a safe no-op (with a single warning).

Supporting exports

Beyond the primary API, @nais/apm also exports DEFAULT_IGNORE_ERRORS, NaisConsoleInstrumentation / CONSOLE_ERROR_PREFIX (the replacement console instrumentation that captures console.error('msg', err) with a real stack trace), resolveConfig / versionFromImage, FEEDBACK_EVENT_NAME, and VERSION. Most apps never need these directly.

Known limitations (0.1.0)

  • No tracing support yet (@grafana/faro-web-tracing integration planned).
  • No @nais/apm/react entry point yet (e.g. an ErrorBoundary).
  • Published to the GitHub Package Registry only.