Replay exactly what your users saw when things went wrong.

Session Replay

Session replay records what users see and do in your app so you can watch a reconstruction of their session when debugging errors. This guide covers enabling replay, configuring privacy controls, and viewing sessions.

Enable Replay

The ReplayRecorder from @codmir/overseer handles session recording. You can configure it through the Overseer client or create a standalone recorder.

Via OverseerClient

import { initOverseer } from '@codmir/overseer';

initOverseer({
  dsn: 'https://your-project.codmir.com/overseer',
  service: 'my-app',
  environment: 'production',
  enableReplay: true,
  replaySampleRate: 0.1,        // Record 10% of all sessions
  replayOnErrorSampleRate: 1.0, // Record 100% of sessions with errors
});

Standalone Recorder

For more control, create a ReplayRecorder directly:

import { createReplayRecorder } from '@codmir/overseer';

const recorder = createReplayRecorder({
  sessionSampleRate: 0.1,
  errorSampleRate: 1.0,
  maxSessionDuration: 60 * 60 * 1000, // 1 hour
  segmentDuration: 5 * 60 * 1000,     // 5-minute segments
});

recorder.start();

The recorder captures DOM snapshots, incremental mutations, mouse movements, clicks, scrolls, input changes, viewport resizes, console logs, and network requests.

Privacy Controls

Replay ships with built-in privacy features. Configure them to protect sensitive data.

import { createReplayRecorder } from '@codmir/overseer';

const recorder = createReplayRecorder({
  sessionSampleRate: 0.1,
  errorSampleRate: 1.0,
  privacy: {
    maskAllInputs: true,
    maskInputTypes: ['password', 'credit-card'],
    maskSelectors: ['[data-private]', '.sensitive-data'],
    blockSelectors: ['[data-block-replay]'],
    ignoreSelectors: ['.replay-ignore'],
  },
});
OptionWhat it does
maskAllInputsReplace all input values with *** in recordings
maskInputTypesMask only specific input types (e.g., password fields)
maskSelectorsCSS selectors for elements whose text content should be masked
blockSelectorsCSS selectors for elements that should be completely hidden
ignoreSelectorsCSS selectors for elements excluded from recording

Per-Element Privacy

Add data attributes directly in your HTML:

<!-- Mask this element's text -->
<div data-private>SSN: 123-45-6789</div>

<!-- Block this entire element from replay -->
<div data-block-replay>
  <CreditCardForm />
</div>

Replay on Error

The most common setup records all sessions that contain an error, while sampling a small percentage of normal sessions:

import { initOverseer } from '@codmir/overseer';

initOverseer({
  dsn: 'https://your-project.codmir.com/overseer',
  service: 'my-app',
  environment: 'production',
  enableReplay: true,
  replaySampleRate: 0,    // Don't record normal sessions
  replayOnErrorSampleRate: 1.0, // Record every session with an error
});

When an error occurs, the recorder retroactively saves the buffered session data. This gives you a full replay without the storage cost of recording every session.

Viewing Sessions with ReplayPlayer

Use ReplayPlayer to play back recorded sessions in your admin dashboard or debugging tools:

import { createReplayPlayer } from '@codmir/overseer';

const player = createReplayPlayer({
  container: document.getElementById('replay-container')!,
  speed: 1,
  skipInactiveThreshold: 5000,
  showCursor: true,
  showClickRipple: true,
  highlightErrors: true,
});

// Load a session
await player.load(replaySession);

// Playback controls
player.play();
player.pause();
player.seek(30000); // Jump to 30 seconds
player.setSpeed(4); // 4x speed

Player Events

Listen for events during playback:

import { createReplayPlayer } from '@codmir/overseer';

const player = createReplayPlayer({
  container: document.getElementById('replay-container')!,
});

player.onStateChange((state) => {
  console.log('Playback state:', state); // 'idle' | 'playing' | 'paused' | 'ended'
});

player.onTimeUpdate((currentTime, duration) => {
  console.log(`${currentTime}ms / ${duration}ms`);
});

player.onError((eventId, timestamp) => {
  console.log('Error occurred at', timestamp);
});

Next Steps