Record session replay safely
Capture browser sessions with privacy masking and connect them to errors and backend traces.
On this page
Session replay is opt-in and available through the JavaScript browser SDK. Record only the journeys you are prepared to store and review.
Start recording
import { startReplay } from '@anectico/sdk/replay';
const stopReplay = startReplay({
endpoint: 'https://app.anectico.com',
apiKey: import.meta.env.VITE_ANECTICO_REPLAY_KEY,
distinctId: currentCustomerId,
maskAllInputs: true,
captureConsole: false,
captureNetwork: false,
slimDOM: 'all',
inlineStylesheet: false,
});
Use a project-scoped browser key with replay:write. Replay chunks are not authorized by
ingest:write. Do not add read, management, or agent scopes to a browser key. The project must
still exist and be active when a chunk is admitted. If its current state cannot be verified,
the upload is refused temporarily; a cached content-policy decision cannot authorize the upload.
Call stopReplay() when the application tears down the recorder. Chunks also flush during normal
page navigation. The stop function is idempotent.
The default sessionId is scoped to the current browser tab and is shared by replay, events, errors,
traces, and logs from that tab. Reloading the tab preserves it; opening or duplicating another tab
creates a separate session/replay boundary. The recorder also preserves its next chunk index across
a same-tab reload. Do not copy one explicit sessionId into recorders in multiple tabs: each tab has
an independent chunk cursor, so their uploads can replace one another. Call identify() after
authentication in each tab and call reset() when that tab logs out. Browser reset() first stops
all active recorders and flushes their buffered prior-user tail, then rotates identity/session. This
prevents the recorder started for one user from capturing the next user's UI. Call startReplay()
again after identifying the next user if recording should resume.
Deleting the owning project or organization permanently blocks later Replay writes once the delete is consumed. Cleanup waits for writers holding the recording locks, and revisits deleted scopes to remove late object uploads whose outcome was uncertain after a connection failure. Stop recording when its owning scope is deleted; retrying cannot recreate that scope.
Keep the defaults private
Input masking is enabled by default. Keep it enabled unless every affected field has been reviewed. Network and console capture are enabled by the SDK unless explicitly disabled, and can include customer or application data. The example starts with both disabled. Enable either one only after reviewing what the application logs or sends and filtering sensitive payloads at the source.
Replay data is opaque at ingestion time; browser-side masking is therefore the important privacy boundary.
Network URL masking removes embedded credentials and masks sensitive query parameters, including nested keys and SPA hash-route queries. Malformed URLs are omitted. Body masking also recognizes encoded form keys and complete quoted secret values. Body limits count UTF-8 bytes.
Response bodies are observed asynchronously through a bounded stream. Bodies exceeding the byte limit, taking longer than one second, or provided without stream support are omitted; metadata can still be recorded. Stopping replay cancels pending reads and prevents later capture events.
Keep large pages responsive
Start the recorder after rendering a small application shell and before progressively mounting a
long feed, table, or virtualized workspace. slimDOM: 'all' removes non-visual metadata from
snapshots. inlineStylesheet: false avoids embedding linked CSS when the replay viewer can load the
same stylesheet URL. These settings reduce recorder parse and snapshot work; they do not disable DOM
mutations, network capture, console capture, or user interactions.
Normal size- and timer-triggered chunks use ordinary requests. Only the final pagehide tail uses a
keepalive request, avoiding the browser's shared keepalive-body quota during large initial
snapshots.
Connect replay to the backend
Keep browser request tracing enabled and allow trace-header propagation to your own API origin. Your
backend must allow the traceparent and baggage request headers and must validate identity at a
trusted boundary.
When this path is configured correctly, a replay can link to the backend trace and error produced by the same session.
Verify
- Start a development session under a recognizable test customer.
- Navigate through the application and trigger a test error.
- Open Analytics → Replays and play the session.
- Confirm the related error and trace are present.
- Open the customer and confirm the replay appears on their timeline.
If the recording is absent or cannot play, see Replay or symbols are not working.