Web (multi-package)

@sankofa/replay-rrweb

rrweb-powered DOM session replay for the web. Privacy-first masking, session correlation, and bandwidth-conscious capture.

@sankofa/replay-rrweb records DOM mutations, mouse moves, clicks, scrolls, and form interactions using the rrweb library, then uploads chunks to the engine where they're correlated to events for one-click playback from the dashboard.

This package is heavier than the others (~28 KB gzipped) because it embeds rrweb. Only register it when you need session replay — most apps don't need it on every page.

Install

bash
npm install @sankofa/replay-rrweb

Register the plugin

TypeScript
import { Sankofa } from "@sankofa/browser";
import { rrwebReplayPlugin } from "@sankofa/replay-rrweb";

Sankofa.init({
apiKey: "sk_live_...",
endpoint: "https://api.sankofa.dev",
plugins: [
  rrwebReplayPlugin({
    flushIntervalMs: 5000,
    maxEventsPerChunk: 250,
  }),
],
});

Recording starts as soon as Sankofa.init resolves. Each session generates one replay file; sessions correlate to replays via $session_id.

Plugin options

The full set of RrwebReplayPluginOptions is documented in the SDK's TypeScript types. Common options:

flushIntervalMsnumber
How often replay chunks are uploaded. Lower = closer to real-time playback, higher = fewer requests.
maxEventsPerChunknumber
Maximum rrweb events per chunk. Smaller chunks = faster playback start but more requests.
maskAllInputsbooleandefault true
Auto-mask all `<input>` and `<textarea>` text values.

For the complete list of options (CSS selectors for blocking / masking specific elements, sampling rate, etc.) inspect the TypeScript types in your IDE — the type definitions are the source of truth.

Privacy and masking

Session replay captures everything the user sees and does — that includes everything your app shows, including PII, payment forms, and authenticated content. Mask aggressively.

By default the plugin enables maskAllInputs, which replaces all text entered into input fields with asterisks. For elements that should be redacted or omitted entirely, use the rrweb-style attributes:

HTML
<!-- Text content of this element gets replaced in the replay. -->
<div data-rrweb-mask>
Account balance: $4,238.14
</div>

<!-- This entire subtree is replaced with a placeholder rectangle. -->
<div data-rrweb-block>
<CreditCardForm />
</div>

Session-replay correlation

Every replay carries:

  • $session_id — same as the events from that session.
  • start_ts, end_ts — bounds of the replay file.

In the dashboard, clicking any event in Live eventsWatch replay scrubs to the moment of that event in the matching session replay. There's no manual stitching to do.

Performance impact

rrweb is built for low overhead — typically 1–3% CPU on modern desktop browsers, slightly higher on low-end mobile. The package adds ~28 KB to your bundle. If page-load performance is critical, defer recording until after first contentful paint:

TypeScript
if (document.readyState === "complete") {
Sankofa.init({ /* ... */, plugins: [rrwebReplayPlugin()] });
} else {
window.addEventListener("load", () => {
  Sankofa.init({ /* ... */, plugins: [rrwebReplayPlugin()] });
});
}

API summary

SymbolDescription
rrwebReplayPlugin(options?)Plugin to register at Sankofa.init.
RrwebReplayPluginOptions (type)The full options interface.

What's next

Edit this page on GitHub