> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squasher.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Next.js SDK

> Capture errors from Next.js routes, middleware, and client boundaries.

Use `@squasher/nextjs` when you want one integration that covers server errors, route handlers, middleware, and client-rendered failures.

## Install

```bash theme={null}
bun add @squasher/nextjs
```

## Initialize

Create `instrumentation.ts` in your project root, or `src/instrumentation.ts` if you use a `src/` layout.

```typescript instrumentation.ts theme={null}
import { init } from "@squasher/nextjs";

export async function register() {
  init({
    apiKey: process.env.SQUASHER_API_KEY!,
    projectId: process.env.SQUASHER_PROJECT_ID!,
    environment: process.env.NODE_ENV,
    release: process.env.NEXT_PUBLIC_GIT_SHA,
  });
}
```

<Note>
  If you run an older Next.js version that requires the instrumentation hook flag, enable it in
  `next.config.js`.
</Note>

## Middleware

```typescript middleware.ts theme={null}
import { NextResponse } from "next/server";
import { withSquasher } from "@squasher/nextjs";

export default withSquasher(async () => NextResponse.next());
```

## Route handlers

```typescript app/api/users/route.ts theme={null}
import { squasherApiHandler } from "@squasher/nextjs";

export const GET = squasherApiHandler(async () => {
  return Response.json({ ok: true });
});
```

## Client error boundaries

```tsx app/providers.tsx theme={null}
"use client";

import { SquasherErrorBoundary } from "@squasher/nextjs/client";

export function Providers({ children }: { children: React.ReactNode }) {
  return (
    <SquasherErrorBoundary fallback={<div>Something went wrong.</div>}>
      {children}
    </SquasherErrorBoundary>
  );
}
```

## Web Vitals

For browser-side Core Web Vitals plus Next.js framework metrics, install `@squasher/browser` and mount a client provider from your root layout:

```bash theme={null}
bun add @squasher/browser
```

```tsx app/squasher-browser-provider.tsx theme={null}
"use client";

import { useEffect } from "react";
import { init } from "@squasher/browser";
import { SquasherNextWebVitals } from "@squasher/browser/next";

let initialized = false;

export function SquasherBrowserProvider() {
  useEffect(() => {
    if (initialized) return;
    initialized = true;

    init({
      apiKey: process.env.NEXT_PUBLIC_SQUASHER_API_KEY!,
      projectId: process.env.NEXT_PUBLIC_SQUASHER_PROJECT_ID!,
      environment: process.env.NODE_ENV,
    });
  }, []);

  return <SquasherNextWebVitals />;
}
```

```tsx app/layout.tsx theme={null}
import { SquasherBrowserProvider } from "./squasher-browser-provider";

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

This captures LCP, CLS, INP, FCP, TTFB, plus the framework metrics Next emits via `useReportWebVitals` (`Next.js-hydration`, `Next.js-route-change-to-render`, `Next.js-render`). Each measurement is tagged with the current pathname so the **Web Vitals** dashboard template can group by route.

## Recommended follow-up

* Upload [source maps](/sdks/source-maps) for readable production traces.
* Use the [Browser SDK](/sdks/browser) if you want a framework-agnostic frontend integration instead.

## Agent handoff

```text theme={null}
Install @squasher/nextjs in this Next.js App Router project. Use instrumentation.ts with export async function register(), wrap route handlers and middleware where useful, add a client provider for browser vitals if requested, and keep all keys in environment variables.
```
