@multiplayer-app/session-recorder-react 1.2.27 → 1.2.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +71 -11
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -302,8 +302,8 @@ class MyErrorBoundary extends React.Component<{ children: React.ReactNode }, { h
302
302
  static getDerivedStateFromError() {
303
303
  return { hasError: true }
304
304
  }
305
- componentDidCatch(error: unknown) {
306
- SessionRecorder.captureException(error as any)
305
+ componentDidCatch(error: unknown, errorInfo?: Record<string, any>) {
306
+ SessionRecorder.captureException(error as any, errorInfo)
307
307
  }
308
308
  render() {
309
309
  return this.state.hasError ? <h1>Oops.</h1> : this.props.children
@@ -313,7 +313,7 @@ class MyErrorBoundary extends React.Component<{ children: React.ReactNode }, { h
313
313
 
314
314
  ### React 18/19 root error hooks
315
315
 
316
- React surfaces recoverable runtime errors via the root option `onRecoverableError`. You can forward these to the session recorder as well. This works in React 18 and React 19.
316
+ React 19 adds `onUncaughtError` and `onCaughtError` to `createRoot` options (along with `onRecoverableError` that exists in 18/19). You can wire all three to `SessionRecorder.captureException` similar to Sentry’s handler:
317
317
 
318
318
  ```tsx
319
319
  import React from 'react'
@@ -325,18 +325,31 @@ SessionRecorder.init({
325
325
  /* ... your config ... */
326
326
  })
327
327
 
328
- ReactDOM.createRoot(document.getElementById('root')!, {
328
+ const container = document.getElementById('root')!
329
+
330
+ const root = ReactDOM.createRoot(container, {
331
+ // React 19: thrown and not caught by an Error Boundary
332
+ onUncaughtError(error, errorInfo) {
333
+ SessionRecorder.captureException(error, { componentStack: errorInfo?.componentStack })
334
+ },
335
+ // React 19: caught by an Error Boundary
336
+ onCaughtError(error, errorInfo) {
337
+ SessionRecorder.captureException(error, { componentStack: errorInfo?.componentStack })
338
+ },
339
+ // React 18/19: recoverable runtime errors
329
340
  onRecoverableError(error) {
330
- SessionRecorder.captureException(error as any)
341
+ SessionRecorder.captureException(error)
331
342
  }
332
- }).render(<App />)
343
+ })
344
+
345
+ root.render(<App />)
333
346
  ```
334
347
 
335
348
  Notes:
336
349
 
337
- - Uncaught errors and unhandled rejections are captured automatically by the browser SDK.
338
- - Error Boundary + `onRecoverableError` covers both render and runtime recoverable errors.
339
- - In Continuous mode, any captured exception marks the trace as ERROR and auto‑saves the rolling session window.
350
+ - Uncaught errors and unhandled promise rejections are captured automatically by the SDK.
351
+ - Error Boundary + root callbacks give the richest context (component stack via `errorInfo.componentStack`).
352
+ - In Continuous mode, captured exceptions set span status ERROR and auto‑save the rolling session window.
340
353
 
341
354
  ## Next.js integration tips
342
355
 
@@ -344,11 +357,58 @@ Notes:
344
357
  - In the App Router, render the `SessionRecorderProvider` at the top of `app/layout.tsx` and add the `NavigationTracker` component inside your root layout so every route change is captured.
345
358
  - If your frontend calls APIs on different origins, set `propagateTraceHeaderCorsUrls` so backend traces correlate correctly.
346
359
 
347
- ### Next.js support (coming soon) and temporary solution
360
+ ### Next.js 15.3+ (App Router) instrumentation-client.ts
361
+
362
+ Next.js 15.3+ adds client-side instrumentation via `src/instrumentation-client.ts`, which runs before hydration. Initialize the recorder at top-level and optionally export `onRouterTransitionStart` for navigation tracking. See the official docs: [instrumentation-client.ts](https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation-client).
363
+
364
+ 1. Create `src/instrumentation-client.ts`:
365
+
366
+ ```ts
367
+ import SessionRecorder from '@multiplayer-app/session-recorder-react'
368
+
369
+ // Initialize as early as possible (before hydration)
370
+ try {
371
+ SessionRecorder.init({
372
+ application: 'my-next-app',
373
+ version: '1.0.0',
374
+ environment: process.env.NEXT_PUBLIC_ENVIRONMENT ?? 'production',
375
+ apiKey: process.env.NEXT_PUBLIC_MULTIPLAYER_API_KEY!,
376
+ showWidget: true,
377
+ // If your APIs are on different origins, add them so OTLP headers are propagated
378
+ // format: string | RegExp | Array
379
+ propagateTraceHeaderCorsUrls: [new RegExp('https://api.example.com', 'i')]
380
+ })
381
+ } catch (error) {
382
+ // Keep instrumentation resilient
383
+ console.warn('[SessionRecorder] init failed in instrumentation-client:', error)
384
+ }
385
+
386
+ // Optional: Next.js will call this when navigation begins
387
+ export function onRouterTransitionStart(url: string, navigationType: 'push' | 'replace' | 'traverse') {
388
+ try {
389
+ SessionRecorder.navigation.record({
390
+ path: url || '/',
391
+ navigationType,
392
+ framework: 'nextjs',
393
+ source: 'instrumentation-client'
394
+ })
395
+ } catch (error) {
396
+ console.warn('[SessionRecorder] navigation record failed:', error)
397
+ }
398
+ }
399
+ ```
400
+
401
+ Notes:
402
+
403
+ - Use `NEXT_PUBLIC_` environment variables for values needed on the client (e.g. `NEXT_PUBLIC_MULTIPLAYER_API_KEY`).
404
+ - `instrumentation-client.ts` ensures initialization happens before your UI mounts; the provider is still required to wire React context and hooks.
405
+ - You can rely on `onRouterTransitionStart` for navigation tracking in Next.js 15.3+, or use the `NavigationTracker` client component as shown below.
406
+
407
+ ### Next.js < 15.3
348
408
 
349
409
  An official Next.js-specific wrapper is coming soon. Until then, you can use this package safely in Next.js by:
350
410
 
351
- 1. Initializing in a Client Component (Recommended)
411
+ 1. Initializing in a Client Component
352
412
 
353
413
  ```tsx
354
414
  'use client'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multiplayer-app/session-recorder-react",
3
- "version": "1.2.27",
3
+ "version": "1.2.28",
4
4
  "description": "Multiplayer Fullstack Session Recorder for React (browser wrapper)",
5
5
  "author": {
6
6
  "name": "Multiplayer Software, Inc.",
@@ -35,8 +35,8 @@
35
35
  "@opentelemetry/api": "^1.9.0"
36
36
  },
37
37
  "dependencies": {
38
- "@multiplayer-app/session-recorder-browser": "1.2.27",
39
- "@multiplayer-app/session-recorder-common": "1.2.27"
38
+ "@multiplayer-app/session-recorder-browser": "1.2.28",
39
+ "@multiplayer-app/session-recorder-common": "1.2.28"
40
40
  },
41
41
  "devDependencies": {
42
42
  "eslint": "8.48.0",