For the complete documentation index, see llms.txt. This page is also available as Markdown.

Connect RUM

This capability is only available to BYOC deployments. Check out our pricing page for more information about subscription plans and the available deployment modes.

groundcover’s Real User Monitoring (RUM) SDK captures front-end performance, user interactions, errors, logs, distributed traces, and session replay from your web application — with privacy masking on by default.

Start capturing RUM data by installing the browser SDK in your web app.

This guide walks you through installing and initializing the SDK, the full configuration reference, identifying users, sending custom events and logs, capturing exceptions, session management, source maps, and session replay.

Install the SDK

npm install @groundcover/browser
# or
yarn add @groundcover/browser

Initialize the SDK

A single init() call installs every instrumentation (page loads, DOM interactions, network requests, errors, console logs, navigation, and performance) and starts sending data. Session replay is the one exception — it must be started explicitly with startReplayRecording().

import groundcover from '@groundcover/browser';

groundcover.init({
  apiKey: 'your-ingestion-key',
  dsn: 'your-dsn',
  cluster: 'your-cluster',
  appId: 'your-app-id',
  environment: 'production',
});

From here you can enrich it:

Configuration

init() takes your connection and identity fields at the top level, plus an options object for behavioral configuration.

Connection & identity

Field
Required
Description

apiKey

A dedicated Ingestion Key of type RUM (Settings → Access → Ingestion Keys).

dsn

Your public groundcover endpoint, in the format https://example.platform.grcv.io, where example.platform.grcv.io is your ingress.site installation value.

cluster

Identifier for your cluster; helps filter RUM data by cluster.

appId

Application identifier; reported as service.name.

environment

Deployment environment (e.g. production, staging) used for filtering.

namespace, releaseId, user, sessionId

Optional identity/grouping fields. releaseId associates uploaded source maps with a release; user matches identifyUser; sessionId enables shared sessions.

Behavioral options

All behavioral configuration lives under options, grouped by concern — sampling (sessionSampleRate, eventSampleRate), enabled instrumentations (enabledEvents), excludedUrls, the beforeSend / enrichEvent hooks, and the privacy, tracing, transport, and replay groups. You can update it at runtime with groundcover.updateConfig(...).

For the complete, always-current configuration reference — every option, type, and default — see the @groundcover/browser package on npm. Data masking is on by default; see Privacy and data masking below.

Privacy and data masking

Masking is on by default (privacy.level: 'mask-sensitive'). A single level is the master switch; finer toggles and hooks refine it.

level

Replay inputs

Replay text

DOM events

Network / logs / errors

mask-sensitive (default)

sensitive masked

[data-private] + maskSelectors masked

sensitive masked

redacted

mask-all

masked

masked (*)

all masked

redacted

allow

off (auth headers are still stripped)

Under mask-sensitive, an input/element is masked when it is a type="password", sits under a [data-private] ancestor or a maskSelectors match, or has an id/name/class/aria-label/placeholder matching a built-in sensitive-key pattern or your sensitiveKeys. Non-sensitive inputs and static page text stay visible; use [data-private] / maskSelectors to mask static content.

Built-in sensitive patterns (always treated as sensitive, case-insensitive; your sensitiveKeys merge on top):

  • Key substrings — matched inside a body/query key or a DOM element attribute (id/name/class/aria-label/placeholder): token, secret, passwd, password, api_key, access_key, write_key, auth, bearer, credential, cvv, ssn, credit_card, card_number (the _ in the last five is optional — apikey / api-key also match).

  • Request/response headers — always stripped regardless of level: authorization, cookie, set-cookie, plus any header name containing token, key, secret, passwd, password, auth, bearer, or credential.

  • Query / form param names — matched as a whole key (not inside JSON bodies), for OAuth-style callbacks: code, state, session_state, id_token, access_token, refresh_token, token.

To turn masking off, set privacy: { level: 'allow' }. Note this disables masking only — auth/request headers are still stripped regardless of level (see the header list above).

Identify Users

Link RUM data to specific users. An omitted key leaves the current identity untouched; pass null via updateConfig to clear it (e.g. on logout).

Send Custom Events

Instrument key user interactions or business events:

Custom event payloads are not auto-redacted (they’re deliberately provided). Scrub sensitive fields yourself, or via enrichEvent.

Capture Exceptions

Manually track caught errors with optional context:

Send Logs

groundcover.logger provides one method per level — log, info, warn, error, debug, trace. The second argument is an attributes object; nested objects are flattened to dotted keys.

The SDK also auto-captures console.* calls; when any argument is a plain object, its keys are promoted to structured log attributes. Reserved keys (message, level, location) are always set by the SDK and can’t be overridden.

Session Management

Read or override the current session id:

Micro-frontend session synchronization

Pass a shared sessionId so multiple frontends report under one session:

Session lifecycle

sessionMaxDuration sets a target maximum wall-clock session length (default 4 hours; must be between 1 minute and 8 hours).

It is enforced lazily, on activity — not by a background timer, so it is not a hard upper bound. Once the cap has elapsed, the next user/business event (click, navigation, log, custom, network, exception, …) flushes pending events under the current session id, mints a fresh id, and resumes replay recording if it had been active.

Because rotation is activity-gated, a session that goes idle keeps its id past the cap until the next qualifying event. Sessions are also bounded by a 30-minute inactivity gap, enforced the same lazy way. The flush is best-effort and the rotation always proceeds regardless of delivery success. Invalid values fall back to the default with a console.warn.

Manual navigation

When navigation isn’t auto-tracked (e.g. a custom router), you can bracket navigation spans manually:

Source Maps

Source maps map minified/bundled code back to your original source files. With them, stack traces in RUM (e.g. in session details and exceptions) show your real file names, line numbers, and function names instead of bundle names and minified positions.

Pre-condition: source maps were enabled in your CI operation.

To enable source maps in your account, upload them from your CI job via the API:

Required form fields:

  • app_id - your application identifier (alphanumeric, dots, hyphens, underscores), as provided in the RUM init call.

  • release_id - the release/version being deployed (same character restrictions), as provided in the RUM init call.

  • file - the source map file.

Required headers:

  • Authorization - groundcover api key - here is how to generate one.

  • X-Backend-Id - the relevant BYOC backend, displayed in the api keys page.

Here is an example of source maps uploading using curl:

Response (201):

Files will be stored in the selected provider at the path: sourcemaps/<app_id>/<release_id>/<filename>.

Every new RUM trace that holds a stack trace will be automatically converted based on the source map.

Session Replay

Session replay records your users’ behavior with rrweb so you can replay the actions that led to specific RUM events.

Replay recording does not start automatically — even when replay is in enabledEvents. You must start it explicitly (for example, after obtaining user consent), and can stop it before a sensitive section of your app:

Recording is stored on your BYOC server and is deleted along with the RUM session, in accordance with your retention policy.

Masking replay content

Replay masking is driven by your privacy config — masking is on by default. To mask specific static content, add the data-private attribute or a maskSelectors match:

rrweb mask options are fixed at record() time. Changing privacy config at runtime via updateConfig automatically restarts the active recording so the new masking applies.

Viewing sessions

In the summary page, you will see an indication next to sessions with a recording.

Within the drawer, open the Session Replay tab to see the recording.

API reference

All methods are available on the default export and on window.groundcover.

Method
Description

init(config)

Initialize the SDK and install instrumentation.

identifyUser(user)

Attach user identity to subsequent events.

sendCustomEvent({ event, attributes })

Emit a custom business event.

captureException(error, metadata?)

Capture a handled error with optional context.

logger.{log,info,warn,error,debug,trace}(message, attributes?)

Structured logging.

updateConfig({ options?, user?, … })

Update config at runtime (merges nested groups one level deep).

startNavigation(metadata) / endNavigation(metadata)

Manual navigation spans (when navigation isn’t auto-tracked).

getSessionId() / setSessionId(id?)

Read / override the current session id.

startReplayRecording() / stopReplayRecording()

Manually control session replay.

Migrating to 1.0.0

1.0.0 restructures options by concern (a clean break from 0.x) and removes the deprecated masking flags. Update your config as follows:

0.x

1.0.0

environment (duplicated in options)

top-level environment only

userIdentifier

user

options.sessionReplay.blockedSelectors

options.replay.blockedSelectors

options.tracePropagationUrls

options.tracing.propagationUrls

options.tracePropagationHeaders

options.tracing.propagationHeaders

options.tracePropagationTraceIdHeaderName

options.tracing.traceIdHeaderName

options.tracePropagationSpanIdHeaderName

options.tracing.spanIdHeaderName

options.traceOrigin

options.tracing.origin

options.batchSize / options.batchTimeout

options.transport.batchSize / options.transport.batchTimeout

options.enableCompression

options.transport.compression

options.enableMasking: true (removed)

set options.privacy.level: 'mask-all'

options.enableMasking: false (removed)

set options.privacy.level: 'allow'

options.maskFields (removed)

set options.privacy.maskSelectors / options.privacy.sensitiveKeys

Last updated