Skip to main content

New Relic

Description

Record Web uses New Relic for back-end APM and profile-aware browser observability. The two agents have different privacy boundaries:

  • The Node agent observes server execution and is enabled by deployment configuration.
  • The Browser agent is installed only after the active profile resolves as Adult. Unresolved and Kids sessions do not load it.
info

By default, New Relic is enabled on production builds. On local and development builds it is disabled unless the application is started with pnpm dev:nr.

Setup

Follow New Relic's Next.js monitoring guide and create the Node and Browser applications for the target environment.

The root newrelic.js file receives its omitted deployment values through NEW_RELIC_APP_NAME and NEW_RELIC_LICENSE_KEY:

NEW_RELIC_APP_NAME=...
NEW_RELIC_LICENSE_KEY=...

The Node policy deliberately disables application log forwarding and broad header collection. It excludes request URIs, request parameters, request headers and response headers so operational APM cannot become an alternate source of profile, content or search data.

Browser release attribution

The root layout performs the existing Node connection and startup checks and generates the Browser timing header once. It resolves the application release using the following precedence:

  1. A trimmed, non-empty NEXT_PUBLIC_APP_VERSION.
  2. The trimmed root package.json version.

addBrowserReleaseAttributes() adds application.version and the compatibility appVersion attribute while preserving existing NREUM.info.jsAttributes. Header augmentation remains fail-open: an unrecognized vendor bootstrap is returned unchanged rather than risking application startup.

Generating the header does not install the Browser agent. The header is passed to MeasurementScriptGate, which inserts it only when allowsCommercialMeasurement is true for an explicitly Adult profile. Maintenance and startup-error documents never render the gate.

Profile transitions

When an Adult session becomes Kids or unresolved, the application clears the New Relic Browser user identity, closes application-owned event paths, removes the bootstrap script and reloads the document. The reload is the final isolation boundary because an already-running third-party browser agent cannot be safely unloaded in place.

A Kids to Adult transition also reloads before Browser instrumentation is installed. This prevents a restricted document and its queued state from being reused for Adult measurement.

Validate a fresh Kids session with browser network capture before release. It must not request js-agent.newrelic.com or the Browser collector, and it must not expose profile, route, content, search or playback fields through New Relic.

Playback error outcomes

Adult playback sessions report Shaka engine errors through the application's player listener, plus any classified error a load() call itself rejects with - Shaka never dispatches its own 'error' event for a load failure, so the player listener alone would miss it. Each CONTENT_ERROR includes the bounded error code, family, severity, whether the error is fatal and the viewer recovery surface (retry_dialog or terminal). A load() rejection that Shaka raised to purposely cancel a superseded load (LOAD_INTERRUPTED, OPERATION_ABORTED) is expected supersession, not a failure, and is not reported. The Shaka SDK's automatic media-element error listener is disabled for every native error Shaka itself mirrors into a classified engine error, so that same failure cannot also emit a second, unclassified error. Shaka swallows MEDIA_ERR_ABORTED without mirroring it, so the SDK's default handling stays active for that one code and reports it unclassified.

The SDK still records whether an error occurred before or after CONTENT_START. A recoverable error before first frame therefore remains startup-degradation evidence, but only an error with playbackErrorFatal = true represents a terminal video-start failure. Kids and unresolved sessions do not create a video tracker or emit playback errors.