npm package: @interfere/next
Description: Build software that never breaks.
Author: Interfere
Latest version: 8.1.0

<p align="center">
  <a href="https://interfere.com">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://qyzkf4cgb8ydxtq1.public.blob.vercel-storage.com/v2/header/logo-dark.png">
      <img src="https://qyzkf4cgb8ydxtq1.public.blob.vercel-storage.com/v2/header/logo-light.png" height="64">
    </picture>
  </a>
  <h1 align="center">@interfere/next</h1>
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@interfere/next"><img src="https://img.shields.io/npm/v/@interfere/next.svg" /></a>
  <a href="https://github.com/interfere-inc/interfere/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@interfere/next.svg" /></a>
  <a href="https://www.npmjs.com/package/@interfere/next"><img src="https://img.shields.io/npm/dm/@interfere/next.svg" /></a>
</p>

<p align="center">
  Next.js SDK for <a href="https://interfere.com">Interfere</a> — error tracking, session replay, and analytics for modern product teams.
</p>

<p align="center">
  <a href="https://support.interfere.com/docs">Documentation</a>
  ·
  <a href="https://support.interfere.com/roadmap">Feature Requests</a>
  ·
  <a href="https://support.interfere.com/requests">Report a Bug</a>
  ·
  <a href="mailto:support@interfere.com">Get Help</a>
</p>

---

## Getting Started

### Prerequisites

- Next.js `>=16`
- React `>=19`
- Node.js `>=20`

### Installation

```bash
npm install @interfere/next
```

### Quick Start

**1. Wrap your Next.js config**

```ts
// next.config.ts
import { withInterfere } from "@interfere/next/config";
import type { NextConfig } from "next";

const config: NextConfig = {};

export default withInterfere(config);
```

**2. Wire instrumentation**

```ts
// instrumentation.ts
export { onRequestError } from "@interfere/next/server";
```

**3. Mount the ingest route**

```ts
// app/api/interfere/[[...path]]/route.ts
export { GET, POST, OPTIONS } from "@interfere/next/route-handler";
```

**4. Add the provider**

```tsx
// app/layout.tsx
import { InterfereProvider } from "@interfere/next/provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <InterfereProvider>{children}</InterfereProvider>
      </body>
    </html>
  );
}
```

### Environment Variables

| Variable | Required | Description |
| --- | --- | --- |
| `INTERFERE_API_KEY` | Yes | Your project API key |

## Identity Management

Link sessions to your authenticated users with `identity.set()`:

```tsx
import { useInterfere } from "@interfere/next/provider";

function useInterfereIdentity() {
  const { identity } = useInterfere();

  // Clerk, Auth0, etc.
  const { user } = useAuthProvider();

  useEffect(() => {
    if (user) {
      identity.set({
        identifier: user.id,
        name: user.name,
        email: user.email,
        source: { type: "clerk", name: "Clerk" },
      });
    } else {
      identity.clear();
    }
  }, [user]);

  return null;
}
```

### Parameters

| Field | Required | Description |
| --- | --- | --- |
| `identifier` | Yes | Unique user ID (your internal ID, not email) |
| `source` | Yes | Auth source: `{ type: "clerk", name: "Clerk" }`, `{ type: "auth0", name: "Auth0" }`, or `{ type: "custom", name: "Your Provider" }` |
| `name` | No | Display name |
| `email` | No | Email address |
| `avatar` | No | Avatar URL |
| `traits` | No | Arbitrary key-value metadata (`Record<string, unknown>`) |

### API

| Method | Description |
| --- | --- |
| `identity.set(params)` | Link the current session to a user. Deduplicated per session — only the first call sends a request. |
| `identity.get()` | Returns the current `IdentifyParams`, or `null` if no identity has been set. |

Identity is automatically cleared when the SDK is closed or the session rotates.

## Consent Management

By default, all SDK features are active. To gate features behind user consent, pass a `consent` prop to the provider:

```tsx
// app/layout.tsx
import { InterfereProvider } from "@interfere/next/provider";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <InterfereProvider consent={{ analytics: true, replay: false }}>
          {children}
        </InterfereProvider>
      </body>
    </html>
  );
}
```

### Consent categories

| Category | Plugins | Gated? |
| --- | --- | --- |
| `necessary` | Error tracking | Always on |
| `analytics` | Page events, rage clicks, fingerprint | Yes |
| `replay` | Session replay | Yes |

Omitting the `consent` prop disables gating entirely (all features load). Passing it enables gating — only `necessary` plugins plus explicitly consented categories will activate.

### Imperative API

Use `consent.set()` and `consent.get()` from the `useInterfere` hook:

```tsx
const { consent } = useInterfere();

consent.set({ analytics: true, replay: true }); // selective
consent.set();                                   // grant all
consent.get();                                   // current state, or null if no gating
```

### Integration with consent libraries

Works with any consent management platform — c15t, CookieYes, OneTrust, etc.:

```tsx
import { InterfereProvider } from "@interfere/next/provider";

function Layout({ children }: { children: React.ReactNode }) {
  const { has } = useConsentManager(); // from your CMP

  return (
    <InterfereProvider
      consent={{ analytics: has("measurement"), replay: has("experience") }}
    >
      {children}
    </InterfereProvider>
  );
}
```

### Initial consent via bootstrap

To set consent before React renders (avoiding any window where non-consented plugins might load), pass it to `init()`:

```ts
// instrumentation-client.ts
import { init } from "@interfere/next/instrument-client";

init({ consent: { analytics: false, replay: false } });
```

The provider's `consent` prop will then keep it in sync as the user updates their preferences.

## What's Included

- **Error tracking** — automatic capture of server and client errors with rich stack traces
- **Session replay** — full visual playback of user sessions
- **Source maps** — automatic upload during production builds
- **Release tracking** — links builds to Git commits and deployments
- **Server capture** — `captureError()` for manual server-side error reporting

## License

MIT