npm package: @prismai/record
Description: Record user sessions in your Next.js application
Latest version: 1.6.6

# @prismai/record

Session recording library for web applications.

## Installation

```bash
npm install @prismai/record
```

## Quick Start

```jsx
import { PrismProvider } from "@prismai/record";

function App() {
  const config = {
    projectId: "your-project-id",
    apiKey: "your-api-key",
  };

  return (
    <PrismProvider config={config}>
      <YourApp />
    </PrismProvider>
  );
}
```

## Next.js Integration

### App Router (Available in Next.js 13+)

For Next.js App Router, use the standard `PrismProvider` in your layout:

```jsx
// app/layout.tsx
import { PrismProvider } from "@prismai/record";

export default function RootLayout({ children }) {
  const config = {
    projectId: "your-project-id",
    apiKey: "your-api-key",
  };

  return (
    <html>
      <body>
        <PrismProvider config={config}>{children}</PrismProvider>
      </body>
    </html>
  );
}
```

### Page Router

For Next.js Page Router, use the specialized `PrismPageRouterProvider` component and `usePageRouterRecorder` hook:

```jsx
// pages/_app.tsx
import { useRouter } from "next/router";
import { PrismPageRouterProvider } from "@prismai/record/client";

export default function App({ Component, pageProps }) {
  const config = {
    projectId: "your-project-id",
    apiKey: "your-api-key",
  };

  const router = useRouter();

  return (
    <PrismPageRouterProvider config={config} router={router}>
      <Component {...pageProps} />
    </PrismPageRouterProvider>
  );
}
```

The `PrismPageRouterProvider` component:
- Handles SSR safely by only mounting the recorder on the client
- Automatically tracks page navigation when provided with the router
- Properly cleans up event listeners when unmounted

When using the Page Router, use the `usePageRouterRecorder` hook (instead of `usePrismRecorder`) to integrate with the Page Router navigation events:

```jsx
// UserProfileComponent.jsx
import { useEffect } from "react";
import { usePageRouterRecorder } from "@prismai/record/client";

function UserProfileComponent({ user }) {
  const { updateVisitorEmail } = usePageRouterRecorder();

  // Update visitor email when user data is available
  useEffect(() => {
    if (user && user.email) {
      updateVisitorEmail(user.email).catch(console.error);
    }
  }, [user, updateVisitorEmail]);

  return <div>User profile content...</div>;
}
```

## Configuration

| Option               | Type    | Required | Default    | Description                              |
| -------------------- | ------- | -------- | ---------- | ---------------------------------------- |
| `projectId`          | string  | Yes      | -          | Your Prism project ID                    |
| `apiKey`             | string  | Yes      | -          | Your Prism API key                       |
| `idleThreshold`      | number  | No       | 5 minutes  | Inactivity threshold before pausing      |
| `sessionTimeout`     | number  | No       | 30 minutes | Inactivity timeout before ending session |
| `maxSessionDuration` | number  | No       | 2 hours    | Max recording duration                   |
| `disabled`           | boolean | No       | false      | Disable recording functionality          |

## Visitor Identification

To identify visitors, use the `updateVisitorEmail` hook. This is the recommended approach for associating user information with recordings.

```jsx
import { PrismProvider, usePrismRecorder } from "@prismai/record";

function App() {
  const config = {
    projectId: "your-project-id",
    apiKey: "your-api-key",
  };

  return (
    <PrismProvider config={config}>
      <YourApp />
    </PrismProvider>
  );
}

function UserProfileComponent({ user }) {
  const { updateVisitorEmail } = usePrismRecorder();

  // Update visitor email when user data is available
  React.useEffect(() => {
    if (user && user.email) {
      updateVisitorEmail(user.email).catch(console.error);
    }
  }, [user, updateVisitorEmail]);

  return <div>User profile content...</div>;
}
```

## Conditionally Disabling Recording

You can conditionally disable recording by using the `disabled` prop:

```jsx
import { PrismProvider } from "@prismai/record";

function App({ user }) {
  const config = {
    projectId: "your-project-id",
    apiKey: "your-api-key",
  };

  // Disable recording based on user preference or environment
  const isRecordingDisabled =
    user.optOut || process.env.NODE_ENV === "development";

  return (
    <PrismProvider config={config} disabled={isRecordingDisabled}>
      <YourApp />
    </PrismProvider>
  );
}
```

## Session Management

- Sessions persist up to 2 hours by default (configurable)
- Continues across page navigation and reloads
- New recording created only when:
  - Session exceeds `maxSessionDuration`
  - Browser tab/window closed and reopened
  - Session manually ended

## Session Control

The `usePrismRecorder` hook provides methods to control recording sessions and update visitor information.

```jsx
import { usePrismRecorder } from "@prismai/record";

function RecordingControls() {
  const {
    endSession, // End the current recording session
    isRecording, // Boolean indicating if recording is active
    updateVisitorEmail, // Update visitor email
  } = usePrismRecorder();

  return (
    <div>
      <p>Recording status: {isRecording ? "Active" : "Inactive"}</p>
      <button onClick={() => void endSession()}>End Recording Session</button>
      <button onClick={() => void updateVisitorEmail("user@example.com")}>
        Update Email
      </button>
    </div>
  );
}
```

## Privacy Options

Prism automatically masks password inputs. Additional masking options can be configured through rrweb parameters when needed.

```jsx
// Basic configuration example
const config = {
  projectId: "your-project-id",
  apiKey: "your-api-key",
};
```

## Technical Notes

- Error boundary prevents recording issues from affecting your app
- Supports Chrome, Firefox, Safari, Edge (latest 2 versions)
- Events sent to Prism API in 2-second batches
- Session automatically ends after inactivity (default: 30 minutes)