Skip to content

Session replay

Session replay reconstructs a real user’s visit from the DOM up. The SDK uses rrweb to capture the DOM, every interaction, scroll, and route change, uploads it as gzipped chunks, and stitches the result per session. Recording is on by default. Each replay is linked to the spans, logs, and errors that occurred during the visit, so you can move from an error group or a slow trace straight to the recording of the session that produced it.

The replay engine (rrweb + pako, ~40 KB gzip) is loaded via dynamic import() only when recording starts, so users on unsampled sessions never download it. The baseline SDK is under 15 KB gzip.

Each chunk is uploaded to object storage through a presigned PUT, and a replay.chunk pointer log is written to the OTLP log stream so replays stay queryable alongside your session logs.

Replay masking is strict by default — no text or input value leaves the browser in the clear unless you opt in:

  • All text nodes render as *** in the replay viewer.
  • All <input>, <textarea>, and <select> values are masked.
  • Whole regions can be replaced with a placeholder using class="osuite-block".
  • Events on entire elements can be excluded with class="osuite-ignore".
  • Per-element opt-back-in for safe text uses class="osuite-unmask".

Annotate elements in your markup to control what replay records:

<span class="osuite-unmask">Hello, Jane</span>
<div class="osuite-block">
<CreditCardForm />
</div>
<button class="osuite-ignore">Internal debug button</button>
  • osuite-unmask — opt a specific element’s text back in, overriding maskAllText.
  • osuite-block — replace the element with a placeholder in replay (payment forms, PII-heavy panels).
  • osuite-ignore — do not record events on the element at all.

The class names are configurable via blockClass, ignoreClass, and unmaskClass in the replay configuration.

  • Masking is on by default. Text is recorded as *** and inputs are masked unless you opt in per element with the classes above.
  • No PII in user.id or extra — by policy. The SDK does not inspect these values; you are responsible for not passing email, phone, or similar.
  • The replay upload JWT is held in memory only — it is never written to localStorage.
  • Trace headers are same-origin only by default, so trace context never leaks to third-party APIs unless you add an explicit allowlist.

All replay options — recording mode, per-session sampleRate, buffer caps, and the masking class names — are documented in the SDK reference. To control which sessions record at all, see Sampling.

  • Frontend errors — jump from an error group to the replay of the session that hit it
  • SDK reference — the full replay configuration table