or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

context-management.mderror-capture.mdindex.mdintegrations.mdperformance-monitoring.mdsdk-initialization.mdsession-management.mdsession-replay.mdtransport.mduser-feedback.md

session-replay.mddocs/

0

# Session Replay

1

2

Complete user session recording and playback capabilities for debugging and understanding user behavior through visual reproduction of user sessions.

3

4

## Capabilities

5

6

### Replay Integration

7

8

Core session replay functionality.

9

10

```typescript { .api }

11

/**

12

* Session replay recording integration

13

* @param options - Replay configuration options

14

* @returns Replay integration

15

*/

16

function replayIntegration(options?: ReplayOptions): Integration;

17

18

/**

19

* Canvas recording for session replay

20

* @param options - Canvas replay options

21

* @returns Canvas replay integration

22

*/

23

function replayCanvasIntegration(options?: ReplayCanvasOptions): Integration;

24

25

/**

26

* Get the current replay client instance

27

* @returns Replay client or undefined

28

*/

29

function getReplay(): ReplayClient | undefined;

30

```

31

32

**Usage Example:**

33

34

```typescript

35

import { replayIntegration, replayCanvasIntegration } from "@sentry/browser";

36

37

Sentry.init({

38

dsn: "YOUR_DSN",

39

integrations: [

40

replayIntegration({

41

sessionSampleRate: 0.1, // 10% of sessions

42

errorSampleRate: 1.0, // 100% of error sessions

43

44

// Privacy settings

45

maskAllText: false,

46

maskAllInputs: true,

47

blockAllMedia: true,

48

49

// Performance settings

50

maxReplayDuration: 60 * 60, // 1 hour max

51

sessionSegmentDuration: 5 * 60, // 5 minute segments

52

}),

53

54

replayCanvasIntegration({

55

enableManualSnapshot: true,

56

fps: 4, // 4 frames per second

57

quality: "medium",

58

}),

59

],

60

});

61

```

62

63

## Types

64

65

### Replay Options

66

67

```typescript { .api }

68

interface ReplayOptions {

69

/** Sample rate for normal sessions (0.0 to 1.0) */

70

sessionSampleRate?: number;

71

72

/** Sample rate for error sessions (0.0 to 1.0) */

73

errorSampleRate?: number;

74

75

/** Mask all text content */

76

maskAllText?: boolean;

77

78

/** Mask all input values */

79

maskAllInputs?: boolean;

80

81

/** Block all media elements (images, videos, audio) */

82

blockAllMedia?: boolean;

83

84

/** CSS selectors for elements to mask */

85

maskTextSelectors?: string[];

86

87

/** CSS selectors for elements to block completely */

88

blockSelectors?: string[];

89

90

/** CSS selectors for elements to ignore during recording */

91

ignoreSelectors?: string[];

92

93

/** Maximum replay duration in seconds */

94

maxReplayDuration?: number;

95

96

/** Duration of each session segment in seconds */

97

sessionSegmentDuration?: number;

98

99

/** Minimum duration before sending a replay */

100

minReplayDuration?: number;

101

102

/** Maximum mutations to capture per second */

103

mutationLimit?: number;

104

105

/** Maximum mutations for breadcrumbs */

106

mutationBreadcrumbLimit?: number;

107

108

/** Timeout for slow clicks in milliseconds */

109

slowClickTimeout?: number;

110

111

/** CSS selectors to ignore for slow click detection */

112

slowClickIgnoreSelectors?: string[];

113

114

/** Network request recording options */

115

networkDetailAllowUrls?: (string | RegExp)[];

116

networkDetailDenyUrls?: (string | RegExp)[];

117

networkCaptureBodies?: boolean;

118

networkRequestHeaders?: string[];

119

networkResponseHeaders?: string[];

120

121

/** Privacy configuration */

122

privacy?: {

123

maskAllText?: boolean;

124

maskAllInputs?: boolean;

125

blockAllMedia?: boolean;

126

maskTextSelectors?: string[];

127

blockSelectors?: string[];

128

};

129

130

/** Callback before sending replay */

131

beforeSend?: (event: ReplayEvent, hint: EventHint) => ReplayEvent | null;

132

133

/** Callback before adding breadcrumb to replay */

134

beforeAddRecordingEvent?: (event: RecordingEvent) => RecordingEvent | null;

135

}

136

```

137

138

### Canvas Replay Options

139

140

```typescript { .api }

141

interface ReplayCanvasOptions {

142

/** Enable manual canvas snapshots */

143

enableManualSnapshot?: boolean;

144

145

/** Recording frame rate (fps) */

146

fps?: number;

147

148

/** Recording quality */

149

quality?: "low" | "medium" | "high";

150

151

/** Maximum canvas width to record */

152

maxCanvasWidth?: number;

153

154

/** Maximum canvas height to record */

155

maxCanvasHeight?: number;

156

157

/** Canvas elements to record (CSS selectors) */

158

recordCanvas?: string[];

159

160

/** Canvas elements to ignore (CSS selectors) */

161

ignoreCanvas?: string[];

162

}

163

```

164

165

### Replay Types

166

167

```typescript { .api }

168

interface ReplayClient {

169

/** Start recording a replay */

170

start(): void;

171

172

/** Stop recording */

173

stop(): void;

174

175

/** Check if currently recording */

176

isEnabled(): boolean;

177

178

/** Get current session ID */

179

getSessionId(): string | undefined;

180

181

/** Flush current replay data */

182

flush(): Promise<void>;

183

184

/** Add breadcrumb to replay */

185

addBreadcrumb(breadcrumb: Breadcrumb): void;

186

}

187

188

type ReplayEventType = "custom" | "fullsnapshot" | "incremental" | "meta";

189

190

interface ReplayEventWithTime {

191

type: ReplayEventType;

192

data: any;

193

timestamp: number;

194

}

195

196

interface ReplayBreadcrumbFrame {

197

type: "breadcrumb";

198

category: string;

199

message?: string;

200

level?: SeverityLevel;

201

timestamp: number;

202

data?: any;

203

}

204

205

interface ReplaySpanFrame {

206

type: "span";

207

op: string;

208

description?: string;

209

startTimestamp: number;

210

endTimestamp?: number;

211

data?: any;

212

}

213

214

interface ReplayFrameEvent {

215

type: ReplayEventType;

216

timestamp: number;

217

data: any;

218

}

219

```

220

221

### Replay Event Structure

222

223

```typescript { .api }

224

interface ReplayEvent {

225

type: "replay_event";

226

replay_id: string;

227

segment_id: number;

228

timestamp: number;

229

replay_start_timestamp: number;

230

urls: string[];

231

error_ids: string[];

232

trace_ids: string[];

233

dist?: string;

234

platform: string;

235

environment?: string;

236

release?: string;

237

user?: User;

238

tags?: { [key: string]: string };

239

extra?: { [key: string]: any };

240

}

241

```

242

243

## Privacy and Security

244

245

### Data Masking

246

247

Replay automatically masks sensitive data:

248

249

```typescript

250

replayIntegration({

251

// Text masking

252

maskAllText: false, // Don't mask all text

253

maskTextSelectors: [

254

'.sensitive-data',

255

'[data-private]',

256

'input[type="password"]',

257

'.ssn',

258

'.credit-card',

259

],

260

261

// Input masking

262

maskAllInputs: true, // Mask all input values by default

263

264

// Element blocking

265

blockSelectors: [

266

'.secret-content',

267

'[data-secret]',

268

'iframe[src*="payment"]',

269

],

270

271

// Media blocking

272

blockAllMedia: true, // Block images, videos, audio

273

});

274

```

275

276

### Network Privacy

277

278

Control network request recording:

279

280

```typescript

281

replayIntegration({

282

// Only record specific API calls

283

networkDetailAllowUrls: [

284

/^https:\/\/api\.mysite\.com\/public/,

285

"https://analytics.example.com",

286

],

287

288

// Exclude sensitive endpoints

289

networkDetailDenyUrls: [

290

/\/api\/auth/,

291

/\/api\/payment/,

292

/\/api\/admin/,

293

],

294

295

// Don't capture request/response bodies

296

networkCaptureBodies: false,

297

298

// Only specific headers

299

networkRequestHeaders: ["content-type", "accept"],

300

networkResponseHeaders: ["content-type", "status"],

301

});

302

```

303

304

## Performance Optimization

305

306

### Sampling Strategy

307

308

Use different sampling rates for different scenarios:

309

310

```typescript

311

replayIntegration({

312

// Low sampling for normal sessions to reduce bandwidth

313

sessionSampleRate: 0.01, // 1% of sessions

314

315

// High sampling for error sessions for debugging

316

errorSampleRate: 1.0, // 100% of error sessions

317

318

// Limit replay duration to control storage

319

maxReplayDuration: 30 * 60, // 30 minutes max

320

321

// Smaller segments for better streaming

322

sessionSegmentDuration: 2 * 60, // 2 minute segments

323

324

// Performance limits

325

mutationLimit: 10000, // Limit DOM changes per second

326

slowClickTimeout: 7000, // 7 second slow click threshold

327

});

328

```

329

330

### Conditional Recording

331

332

Start/stop recording based on conditions:

333

334

```typescript

335

import { getReplay } from "@sentry/browser";

336

337

// Start recording on user action

338

function startRecordingSession() {

339

const replay = getReplay();

340

if (replay) {

341

replay.start();

342

}

343

}

344

345

// Stop recording when leaving sensitive area

346

function stopRecordingForPrivacy() {

347

const replay = getReplay();

348

if (replay) {

349

replay.stop();

350

}

351

}

352

353

// Conditional recording based on user consent

354

if (userHasConsentedToRecording) {

355

startRecordingSession();

356

}

357

```

358

359

## Canvas Recording

360

361

Record HTML5 canvas elements:

362

363

```typescript

364

replayCanvasIntegration({

365

// Record specific canvas elements

366

recordCanvas: ["#game-canvas", ".chart-canvas"],

367

368

// Performance settings

369

fps: 2, // Low frame rate for performance

370

quality: "medium",

371

372

// Size limits

373

maxCanvasWidth: 1920,

374

maxCanvasHeight: 1080,

375

376

// Manual snapshot mode for better performance

377

enableManualSnapshot: true,

378

});

379

```

380

381

## Best Practices

382

383

### Privacy-First Configuration

384

385

```typescript {.api}

386

replayIntegration({

387

// Conservative privacy defaults

388

maskAllInputs: true,

389

blockAllMedia: true,

390

maskTextSelectors: [".pii", "[data-sensitive]"],

391

blockSelectors: [".admin-only", "[data-secret]"],

392

393

// No network details by default

394

networkDetailAllowUrls: [],

395

networkCaptureBodies: false,

396

397

// Before send filtering

398

beforeSend: (event) => {

399

// Additional privacy checks

400

if (containsSensitiveData(event)) {

401

return null;

402

}

403

return event;

404

},

405

});

406

```