Skip to content

Session replay

Session replay records the DOM of sampled sessions and lets you watch them back in the panel, side by side with the session’s events. It’s built for debugging and UX research, and it’s deliberately conservative: off by default, sampled by default, inputs masked by default.

One switch: project settings. Enable session recording and set the project-level sample rate in the panel, and the SDK picks it up on its own (via /decide) — no code change or deploy needed. The same switch is the remote kill switch: turning it off stops new recordings within seconds.

The SDK’s sessionRecording init option is for local overrides — privacy options, or opting out entirely:

kilden.init('YOUR_WRITE_KEY', {
sessionRecording: {
sampleRate: 0.1, // record 10% of sessions
maskAllInputs: true, // default — see privacy below
minimumDurationMs: 2000, // drop sub-2s noise
},
});

A local sessionRecording: false always wins over remote config — the recording code isn’t even downloaded. See the SDK reference for eager vs lazy loading and the manual startSessionRecording() / stopSessionRecording() controls.

Recording 100% of sessions is expensive for everyone involved; the default records 10%. The decision is made once per session and is sticky: reloads keep it, and it re-rolls when the session rotates after 30 minutes of inactivity. The effective sample rate can also be set remotely from project settings.

Replay’s defaults are deliberately stricter than autocapture’s, because a recording shows what the user types:

Control Default Effect
maskAllInputs true Everything typed into inputs is masked. Turning this off is an explicit decision
maskAllText false Mask all page text, not just inputs
blockSelectors Elements matching these selectors are not recorded at all
recordCanvas false Canvas contents are skipped

Two DOM attributes work across the whole SDK:

  • data-kilden-no-capture — excludes the element and its descendants from autocapture and from recordings entirely.
  • data-kilden-mask — records the structure but masks the content (text and inputs) of the element and its descendants.
<section data-kilden-mask>
<!-- layout visible in the replay, contents masked -->
</section>

A recording shares its session id with the session’s events, so replays and event timelines join 1:1 — “watch the sessions of everyone who abandoned checkout” is a query, not a search. When recording starts, the SDK emits $session_recording_started into your event stream. A recording never crosses a session boundary: session rotation cuts it.

Replay data does not travel with your events: chunks are gzip-compressed in the browser and posted to {apiHost}/replay (max 4 MiB per chunk), with recording metadata in headers — never in the URL, so nothing sensitive lands in access logs. Short sessions (under minimumDurationMs, default 2 s) are discarded. Recordings are retained for 30 days.