Session Replay
Session replay lets you watch exactly what a user saw and did — mouse movements, clicks, scrolls, and page changes — all reconstructed from recorded DOM events.
Enable replay
haya.init('YOUR_SDK_KEY', {
sessionReplay: true,
maskInputs: true, // Always recommended in production
});
How it works
Haya uses rrweb under the hood. Instead of recording a video, rrweb captures a series of DOM snapshots and mutations. When you play a replay in the dashboard, those events are replayed in a sandboxed iframe — reconstructing the exact DOM state the user saw.
This approach has major advantages over video:
- Much smaller file size — a 40-second session is typically 50–200 KB, not MB
- Text is selectable — you can copy content from the replay
- Privacy-safe — sensitive elements can be masked at the DOM level
Continuous recording
Replay recording works in rolling chunks. After each chunk reaches the configured duration (default 40 seconds), it is uploaded to storage and a new recording starts automatically — covering the next 40 seconds of the session, and so on for as long as the user stays on the page.
Each uploaded chunk replaces the previous one on the session record, so the dashboard always shows the most recent replay segment. Regular event tracking (clicks, scrolls, pageviews) runs alongside recording and is never interrupted.
To change the chunk duration:
haya.init('YOUR_SDK_KEY', {
sessionReplay: true,
replayMaxDuration: 60, // seconds per chunk
});
Privacy and masking
Mask all inputs (recommended)
haya.init('YOUR_SDK_KEY', {
sessionReplay: true,
maskInputs: true,
});
With maskInputs: true, every <input>, <textarea>, and <select> shows as *** in the replay. The user's actual data is never captured.
Mask specific elements
Add the haya-block class to any element you want to completely hide in replays:
<div class="haya-block">
<!-- This entire section will appear as a solid block in the replay -->
<p>{{ user.creditCardNumber }}</p>
</div>
Ignore elements from tracking entirely
haya.init('YOUR_SDK_KEY', {
ignoreSelectors: ['.sensitive-widget'],
});
One session per page load
Each call to haya.init() starts a new session with a fresh session ID. This means every page load creates its own independent session and replay recording. The session starts the moment the page loads and the rrweb FullSnapshot is taken.
A persistent device ID is stored in localStorage so all sessions from the same browser can be linked together in the dashboard — but each page load gets its own replay.
This design keeps replays short and focused (one user flow = one replay) and means there is no state to clean up between navigations.
Viewing replays
In your Haya dashboard, go to Sessions and click any session with a replay icon. Sessions without a completed replay are still listed — they just show Replay pending or No replay depending on their status.
A session replay goes through these statuses:
| Status | Meaning |
|---|---|
active | Session is live — replay chunks are accumulating |
replay_processing | Chunk limit reached — a background worker is uploading to storage |
replay_ready | Latest replay chunk is available to watch |
completed | Session ended without enough replay data to upload |
Storage
Replays are stored as NDJSON files (one rrweb event per line) in Cloudinary under Haya/replays/. The replayUrl on the session document points directly to the file. Replay files follow the same 90-day retention policy as all other analytics data.