---
title: "Manual Setup"
description: "Learn how to set up and configure Sentry in your Next.js application, capture your first errors, logs and traces and view them in Sentry."
url: https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
---

# Manual Setup | Sentry for Next.js

For the fastest setup, we recommend using the [wizard installer](https://docs.sentry.io/platforms/javascript/guides/nextjs.md).

This guide covers manual setup for **Next.js 15+ with Turbopack and App Router**. For other setups, see:

* [Pages Router Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/pages-router.md) - For applications using the Pages Router
* [Webpack Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/webpack-setup.md) - For applications not using Turbopack

## [Prerequisites](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#prerequisites)

You need:

* A Next.js application
* A Sentry [account](https://sentry.io/signup/) and [project](https://docs.sentry.io/product/projects.md)

Choose the features you want to configure:

Error Monitoring\[x]Tracing\[ ]Session Replay\[ ]User Feedback

**How this guide works:**

1. **Install** - Add the Sentry SDK to your project
2. **Configure** - Set up SDK initialization files and Next.js configuration
3. **Verify** - Test error monitoring and any additional features you enabled

## [Install](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#install)

### [Install the Sentry SDK](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#install-the-sentry-sdk)

Run the command for your preferred package manager to add the Sentry SDK to your application.

```bash
npm install @sentry/nextjs --save
```

*Other available variations of the above snippet: yarn, pnpm*

## [Configure](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#configure)

### [Apply Instrumentation to Your App](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#apply-instrumentation-to-your-app)

Extend your app's default Next.js options by adding `withSentryConfig` into your `next.config.ts` file.

```typescript
import type { NextConfig } from "next";
import { withSentryConfig } from "@sentry/nextjs";

const nextConfig: NextConfig = {
  // Your existing Next.js configuration
};

export default withSentryConfig(nextConfig, {
  org: "<your-org-slug>",
  project: "<your-project-slug>",

  // Only print logs for uploading source maps in CI
  silent: !process.env.CI,
});
```

### [Initialize Sentry SDKs](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#initialize-sentry-sdks)

Create the following files in your application's root directory (or `src` folder if you have one):

* `instrumentation-client.ts` - Client-side SDK initialization
* `sentry.server.config.ts` - Server-side SDK initialization
* `sentry.edge.config.ts` - Edge runtime SDK initialization

##### Tip

Include your DSN directly in these files, or use a *public* environment variable like `NEXT_PUBLIC_SENTRY_DSN`.

**\[Client] instrumentation-client.ts**

```typescript
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  // ___PRODUCT_OPTION_START___ performance

  // Capture 100% in dev, 10% in production
  // Adjust based on your traffic volume
  tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
  // ___PRODUCT_OPTION_END___ performance
  integrations: [
    // ___PRODUCT_OPTION_START___ session-replay
    Sentry.replayIntegration(),
    // ___PRODUCT_OPTION_END___ session-replay
    // ___PRODUCT_OPTION_START___ user-feedback
    Sentry.feedbackIntegration({
      colorScheme: "system",
    }),
    // ___PRODUCT_OPTION_END___ user-feedback
  ],
  // ___PRODUCT_OPTION_START___ session-replay

  // Capture Replay for 10% of all sessions,
  // plus for 100% of sessions with an error
  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
  // ___PRODUCT_OPTION_END___ session-replay
});

// ___PRODUCT_OPTION_START___ performance
// This export will instrument router navigations
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
// ___PRODUCT_OPTION_END___ performance
```

**\[Server] sentry.server.config.ts**

```typescript
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  // ___PRODUCT_OPTION_START___ performance

  // Capture 100% in dev, 10% in production
  // Adjust based on your traffic volume
  tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
  // ___PRODUCT_OPTION_END___ performance
});
```

**\[Edge] sentry.edge.config.ts**

```typescript
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  // ___PRODUCT_OPTION_START___ performance

  // Capture 100% in dev, 10% in production
  // Adjust based on your traffic volume
  tracesSampleRate: process.env.NODE_ENV === "development" ? 1.0 : 0.1,
  // ___PRODUCT_OPTION_END___ performance
});
```

##### Adjust sample rates for production

The example above samples 100% of traces in development and 10% in production. Monitor your [usage stats](https://sentry.io/orgredirect/organizations/:orgslug/settings/stats/?dataCategory=spans) and adjust `tracesSampleRate` based on your traffic volume. Learn more about [sampling configuration](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/sampling.md).

### [Register Server-Side SDK](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#register-server-side-sdk)

Create a [Next.js Instrumentation file](https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation) named `instrumentation.ts` in your project root (or `src` folder). This file imports your server and edge configurations and exports `onRequestError` to capture server-side errors.

The `onRequestError` hook requires `@sentry/nextjs` version `8.28.0` or higher and Next.js 15.

```typescript
import * as Sentry from "@sentry/nextjs";

export async function register() {
  if (process.env.NEXT_RUNTIME === "nodejs") {
    await import("./sentry.server.config");
  }

  if (process.env.NEXT_RUNTIME === "edge") {
    await import("./sentry.edge.config");
  }
}

// Capture errors from Server Components, middleware, and proxies
export const onRequestError = Sentry.captureRequestError;
```

### [Capture React Render Errors](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#capture-react-render-errors)

Create `app/global-error.tsx` to capture errors that occur anywhere in your App Router application.

```tsx
"use client";

import * as Sentry from "@sentry/nextjs";
import NextError from "next/error";
import { useEffect } from "react";

export default function GlobalError({
  error,
}: {
  error: Error & { digest?: string };
}) {
  useEffect(() => {
    Sentry.captureException(error);
  }, [error]);

  return (
    <html>
      <body>
        {/* `NextError` is the default Next.js error page component. Its type
        definition requires a `statusCode` prop. However, since the App Router
        does not expose status codes for errors, we simply pass 0 to render a
        generic error message. */}
        <NextError statusCode={0} />
      </body>
    </html>
  );
}
```

*Other available variations of the above snippet: jsx*

### [Server Actions](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#server-actions)

Wrap your Server Actions with `Sentry.withServerActionInstrumentation()`.

```typescript
"use server";
import * as Sentry from "@sentry/nextjs";
import { headers } from "next/headers";

export async function submitForm(formData: FormData) {
  return Sentry.withServerActionInstrumentation(
    "submitForm", // Action name for Sentry
    {
      headers: await headers(), // Connect client and server traces
      formData, // Attach form data to events
      recordResponse: true, // Include response data
    },
    async () => {
      // Your server action logic
      const result = await processForm(formData);
      return { success: true, data: result };
    },
  );
}
```

### [Source Maps (Optional)](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#source-maps-optional)

Add the `authToken` option to your `next.config.ts` to enable readable stack traces. Set the `SENTRY_AUTH_TOKEN` environment variable in your CI/CD.

##### Important

Keep your auth token secret and out of version control.

```typescript
export default withSentryConfig(nextConfig, {
  org: "<your-org-slug>",
  project: "<your-project-slug>",

  // Pass the auth token
  authToken: process.env.SENTRY_AUTH_TOKEN,

  // Upload a larger set of source maps for prettier stack traces
  widenClientFileUpload: true,
});
```

*Other available variations of the above snippet: sh*

### [Tunneling (Optional)](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#tunneling-optional)

Prevent ad blockers from blocking Sentry events by routing them through your Next.js server.

This increases server load. Consider the trade-off for your application.

Using Next.js proxy (middleware) with tunneling

If you're using Next.js proxy/middleware that intercepts requests, exclude the tunnel route. The file is called `proxy.ts` in Next.js 16+ and `middleware.ts` in Next.js 15:

```typescript
export const config = {
  matcher: ["/((?!sentry-tunnel|_next/static|_next/image|favicon.ico).*)"],
};
```

```typescript
export default withSentryConfig(nextConfig, {
  // Use a fixed route (recommended)
  tunnelRoute: "/sentry-tunnel",
});
```

### [Control the Data You Send to Sentry (Optional)](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#control-the-data-you-send-to-sentry-optional)

By default, the SDK sends user identity data (IP address, ID, and similar) and other data like HTTP bodies and URL query parameters. This will give you rich debugging context.

The SDK always filters sensitive values whose keys match a built-in denylist, such as `auth` or `password`, and sends `[Filtered]` instead.

To send less data, turn off the categories you don't need in the `dataCollection` option. For the full list of categories and their defaults, [see the `dataCollection` options](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options.md#dataCollection).

```javascript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",
  dataCollection: {
    userInfo: false,
    // other categories
  },
});
```

## [Error Monitoring](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#error-monitoring)

Test your error monitoring setup by throwing an error and viewing it in Sentry.

### [Throw a Test Error](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#throw-a-test-error)

Add this button to any page and click it to trigger a test error.

##### Important

Errors triggered from within your browser's developer tools (like the browser console) are sandboxed, so they will not trigger Sentry's error monitoring.

```jsx
<button
  type="button"
  onClick={() => {
    throw new Error("Sentry Test Error");
  }}
>
  Break the world
</button>;
```

### [Verify](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#verify)

Open [**Issues**](https://sentry.io/orgredirect/organizations/:orgslug/issues/) in Sentry to see your test error. [Learn more about capturing errors](https://docs.sentry.io/platforms/javascript/guides/nextjs/capturing-errors.md).

## [Verify Additional Features](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#verify-additional-features)

Based on the features you selected above, verify each one is working correctly.

### [Session Replay](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#session-replay)

Session Replay captures video-like reproductions of user sessions. It's configured with `replayIntegration()` in your client config.

By default, Sentry masks all text, inputs, and media. You can customize this in [Privacy Configuration](https://docs.sentry.io/platforms/javascript/guides/nextjs/session-replay/privacy.md).

**Verify:** Trigger an error or navigate your app, then check [**Replays**](https://sentry.io/orgredirect/organizations/:orgslug/replays/) in Sentry.

```typescript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  integrations: [
    Sentry.replayIntegration({
      maskAllText: true,
      maskAllInputs: true,
      blockAllMedia: true,
    }),
  ],

  replaysSessionSampleRate: 0.1,
  replaysOnErrorSampleRate: 1.0,
});
```

### [Tracing](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#tracing)

Tracing is configured with `tracesSampleRate` in your SDK init files. Next.js routes and API calls are automatically instrumented.

Add [custom spans](https://docs.sentry.io/platforms/javascript/guides/nextjs/tracing/instrumentation/custom-instrumentation.md) to trace specific operations in your code.

**Verify:** Navigate to any page, then check [**Traces**](https://sentry.io/orgredirect/organizations/:orgslug/explore/traces/) in Sentry.

```typescript
import * as Sentry from "@sentry/nextjs";

// Wrap operations with spans
const result = await Sentry.startSpan(
  { name: "expensive-operation", op: "function" },
  async () => {
    return await fetchDataFromAPI();
  },
);
```

### [Logs](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#logs)

Logs are enabled by default. Use the Sentry logger to send structured logs from anywhere in your application.

Connect popular logging libraries via [Integrations](https://docs.sentry.io/platforms/javascript/guides/nextjs/logs.md#integrations).

**Verify:** Add a log statement, trigger it, then check [**Logs**](https://sentry.io/orgredirect/organizations/:orgslug/explore/logs/) in Sentry.

```typescript
import * as Sentry from "@sentry/nextjs";

Sentry.logger.info("User clicked checkout button");

Sentry.logger.info("Order completed", {
  orderId: "12345",
  total: 99.99,
});

Sentry.logger.warn("Warning message");
Sentry.logger.error("Error occurred");
```

### [User Feedback](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup.md#user-feedback)

User Feedback adds an embeddable widget via `feedbackIntegration()` that lets users report bugs directly from your app.

**Verify:** Look for the feedback button (bottom-right corner), submit test feedback, then check [**User Feedback**](https://sentry.io/orgredirect/organizations/:orgslug/feedback/) in Sentry.

[Learn more about User Feedback](https://docs.sentry.io/platforms/javascript/guides/nextjs/user-feedback.md)

```typescript
Sentry.init({
  dsn: "https://<key>@o<orgId>.ingest.sentry.io/<projectId>",

  integrations: [
    Sentry.feedbackIntegration({
      colorScheme: "system",
    }),
  ],
});
```

## Hybrid Apps (App Router + Pages Router)

If your application uses both the App Router and Pages Router:

1. Follow this guide for App Router components
2. Add a `pages/_error.tsx` file for Pages Router error handling (see [Pages Router Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/pages-router.md))
3. Both routers share the same Sentry configuration files

The Sentry SDK automatically detects which router is being used and applies the appropriate instrumentation.

## Next Steps

You've successfully integrated Sentry into your Next.js application! Here's what to explore next:

* [Logs Integrations](https://docs.sentry.io/platforms/javascript/guides/nextjs/logs.md#integrations) - Connect popular logging libraries like Pino, Winston, and Bunyan
* [Distributed Tracing](https://docs.sentry.io/platforms/javascript/guides/nextjs/tracing/distributed-tracing.md) - Trace requests across services and microservices
* [Agent Tracing](https://docs.sentry.io/platforms/javascript/guides/nextjs/agent-tracing.md) - Monitor agents built with Vercel AI SDK, LangChain, and more
* [Connect GitHub + Seer](https://docs.sentry.io/integrations/source-code-mgmt/github.md#installing-github) - Enable AI-powered [root cause analysis](https://docs.sentry.io/product/ai-in-sentry/seer.md) by connecting your GitHub repository
* [Configuration Options](https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration.md) - Explore extended SDK configuration options

Are you having problems setting up the SDK?

* Try the [installation wizard](https://docs.sentry.io/platforms/javascript/guides/nextjs.md) for automatic setup
* [Get support](https://www.sentry.help/en/)

## Pages in this section

- [Pages Router Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/pages-router.md)
- [Webpack Setup](https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/webpack-setup.md)
