Manual Setup
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.
For the fastest setup, we recommend using the wizard installer.
This guide covers manual setup for Next.js 15+ with Turbopack and App Router. For other setups, see:
- Pages Router Setup - For applications using the Pages Router
- Webpack Setup - For applications not using Turbopack
You need:
Choose the features you want to configure:
How this guide works:
- Install - Add the Sentry SDK to your project
- Configure - Set up SDK initialization files and Next.js configuration
- Verify - Test error monitoring and any additional features you enabled
Run the command for your preferred package manager to add the Sentry SDK to your application.
npm install @sentry/nextjs --save
Extend your app's default Next.js options by adding withSentryConfig into your next.config.ts file.
next.config.tsimport type { NextConfig } from "next";
import { withSentryConfig } from "@sentry/nextjs";
const nextConfig: NextConfig = {
// Your existing Next.js configuration
};
export default withSentryConfig(nextConfig, {
org: "___ORG_SLUG___",
project: "___PROJECT_SLUG___",
// Only print logs for uploading source maps in CI
silent: !process.env.CI,
});
Create the following files in your application's root directory (or src folder if you have one):
instrumentation-client.ts- Client-side SDK initializationsentry.server.config.ts- Server-side SDK initializationsentry.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.
instrumentation-client.tsimport * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "___PUBLIC_DSN___",
// Adds request headers and IP for users
sendDefaultPii: true,
// ___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
// ___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___ logs
// Enable logs to be sent to Sentry
enableLogs: true,
// ___PRODUCT_OPTION_END___ logs
});
// ___PRODUCT_OPTION_START___ performance
// This export will instrument router navigations
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
// ___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 and adjust tracesSampleRate based on your traffic volume. Learn more about sampling configuration.
Create a Next.js Instrumentation file 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.
instrumentation.tsimport * 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;
Create app/global-error.tsx to capture errors that occur anywhere in your App Router application.
global-error.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>
);
}
Wrap your Server Actions with Sentry.withServerActionInstrumentation().
app/actions.ts"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 };
},
);
}
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.
next.config.tsexport default withSentryConfig(nextConfig, {
org: "___ORG_SLUG___",
project: "___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,
});
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.
next.config.tsexport default withSentryConfig(nextConfig, {
// Use a fixed route (recommended)
tunnelRoute: "/monitoring",
});
Test your error monitoring setup by throwing an error and viewing it in Sentry.
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.
<button
type="button"
onClick={() => {
throw new Error("Sentry Test Error");
}}
>
Break the world
</button>;
Open Issues in Sentry to see your test error. Learn more about capturing errors.
Based on the features you selected above, verify each one is working correctly.
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.
Verify: Trigger an error or navigate your app, then check Replays in Sentry.
instrumentation-client.tsSentry.init({
dsn: "___PUBLIC_DSN___",
integrations: [
Sentry.replayIntegration({
maskAllText: true,
maskAllInputs: true,
blockAllMedia: true,
}),
],
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
Tracing is configured with tracesSampleRate in your SDK init files. Next.js routes and API calls are automatically instrumented.
Add custom spans to trace specific operations in your code.
Verify: Navigate to any page, then check Traces in Sentry.
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 are enabled with enableLogs: true in your SDK config. Use the Sentry logger to send structured logs from anywhere in your application.
Connect popular logging libraries via Integrations.
Verify: Add a log statement, trigger it, then check Logs in Sentry.
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 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 in Sentry.
instrumentation-client.tsSentry.init({
dsn: "___PUBLIC_DSN___",
integrations: [
Sentry.feedbackIntegration({
colorScheme: "system",
}),
],
});
Hybrid Apps (App Router + Pages Router)
If your application uses both the App Router and Pages Router:
- Follow this guide for App Router components
- Add a
pages/_error.tsxfile for Pages Router error handling (see Pages Router Setup) - 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 - Connect popular logging libraries like Pino, Winston, and Bunyan
- Distributed Tracing - Trace requests across services and microservices
- AI Agent Monitoring - Monitor AI agents built with Vercel AI SDK, LangChain, and more
- Connect GitHub + Seer - Enable AI-powered root cause analysis by connecting your GitHub repository
- Configuration Options - Explore extended SDK configuration options
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").