Manual Setup
Learn how to set up the SDK manually.
If you can't (or prefer not to) run the automatic setup, you can follow the instructions below to configure your application.
npm install @sentry/nextjs --save
If you're updating your Sentry SDK to the latest version, check out our migration guide to learn more about breaking changes.
Use withSentryConfig to extend the default Next.js options. This will apply instrumentation to your application.
Include the following in your next.config.js or next.config.mjs:
next.config.jsconst { withSentryConfig } = require("@sentry/nextjs");
const nextConfig = {
// Your existing Next.js configuration
};
// Make sure adding Sentry options is the last code to run before exporting
module.exports = withSentryConfig(nextConfig, {
org: "example-org",
project: "example-project",
// An auth token is required for uploading source maps.
authToken: process.env.SENTRY_AUTH_TOKEN,
silent: false, // Can be used to suppress logs
});
withSentryConfig uses a custom Webpack plugin to manage your sourcemaps and releases under the hood. If withSentryConfig does not provide the option you need to modify, you may override the sentryWebpackPluginOptions directly via unstable_sentryWebpackPluginOptions.
Note that this option is unstable and its API may include breaking changes in any release.
Create three files in the root directory of your Next.js application: sentry.client.config.js, sentry.server.config.js and sentry.edge.config.js. In these files, add your initialization code for the client-side SDK and server-side SDK, respectively. We've included some examples below.
Please note that there are slight differences between these files since they run in different places (browser, server, edge), so copy them carefully!
sentry.client.config.(js|ts)import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// Replay may only be enabled for the client-side
integrations: [Sentry.replayIntegration()],
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for tracing.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
// ...
// Note: if you want to override the automatic release value, do not set a
// `release` value here - use the environment variable `SENTRY_RELEASE`, so
// that it will also get attached to your source maps
});
We recommend you include your DSN directly in these three files. Alternatively you can pass the DSN via a public environment variable like NEXT_PUBLIC_SENTRY_DSN.
While the client initialization code will be injected into your application's client bundle by withSentryConfig which we set up earlier, the configuration for the server and edge runtime needs to be imported from a Next.js Instrumentation file. To set up this file, enable the Next.js instrumentation hook by setting the experimental.instrumentationHook to true in your next.config.js. Then add a instrumentation.ts file to the root directory of your Next.js application (or inside the src folder if you're using one) and add the following content:
instrumentation.(js|ts)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");
}
}
Make sure that the import statements point to your newly created sentry.server.config.(js|ts) and sentry.edge.config.(js|ts) files.
To capture React render errors you need to add Error components for the App Router and the Pages Router respectively.
Create a Custom Next.js Global Error component for the App router:
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>
);
}
Note that if you create Next.js error.js files, these files will take precedence over the global-error.js file. This means, that if you want to report errors that are caught by error.js files, you need to manually capture them:
error.tsx"use client";
import { useEffect } from "react";
import * as Sentry from "@sentry/nextjs";
export default function ErrorPage({
error,
}: {
error: Error & { digest?: string };
}) {
useEffect(() => {
// Log the error to Sentry
Sentry.captureException(error);
}, [error]);
return (
<div>
<h2>Something went wrong!</h2>
</div>
);
}
Requires @sentry/nextjs version 8.28.0 or higher and Next.js 15.
To capture errors from nested React Server Components, use the onRequestError hook in instrumentation.(js|ts). The onRequestError hook is a feature provided by Next.js, which allows reporting errors to Sentry.
To report errors using the onRequestError hook, pass all arguments to the captureRequestError function:
instrumentation.tsimport * as Sentry from "@sentry/nextjs";
export const onRequestError = Sentry.captureRequestError;
If you need additional logic within the onRequestError hook, call captureRequestError with all arguments passed to onRequestError:
instrumentation.tsimport * as Sentry from "@sentry/nextjs";
import type { Instrumentation } from 'next';
export const onRequestError: Instrumentation.onRequestError = (...args) => {
Sentry.captureRequestError(...args);
// ... additional logic here
};
Create a Custom Next.js Error Page and call captureUnderscoreErrorException in your Error Page's getInitialProps method:
_error.tsximport * as Sentry from "@sentry/nextjs";
import type { NextPage } from "next";
import type { ErrorProps } from "next/error";
import Error from "next/error";
const CustomErrorComponent: NextPage<ErrorProps> = (props) => {
return <Error statusCode={props.statusCode} />;
};
CustomErrorComponent.getInitialProps = async (contextData) => {
// In case this is running in a serverless function, await this in order to give Sentry
// time to send the error before the lambda exits
await Sentry.captureUnderscoreErrorException(contextData);
// This will contain the status code of the response
return Error.getInitialProps(contextData);
};
export default CustomErrorComponent;
Requires @sentry/nextjs SDK version 7.81.0 or newer.
To instrument Next.js Server Actions, wrap their content in withServerActionInstrumentation, along with a name to describe your server action.
You can optionally pass form data and headers to record them, and configure the wrapper to record the Server Action responses:
import * as Sentry from "@sentry/nextjs";
import { headers } from "next/headers";
export default function ServerComponent() {
async function myServerAction(formData: FormData) {
"use server";
return await Sentry.withServerActionInstrumentation(
"myServerAction", // The name you want to associate this Server Action with in Sentry
{
formData, // Optionally pass in the form data
headers: headers(), // Optionally pass in headers
recordResponse: true, // Optionally record the server action response
},
async () => {
// ... Your Server Action code
return { name: "John Doe" };
},
);
}
return (
<form action={myServerAction}>
<input type="text" name="some-input-value" />
<button type="submit">Run Action</button>
</form>
);
}
By default, withSentryConfig will add a custom Webpack plugin to your configuration that runs for both server and client builds. This means that when you run a production build (next build), sourcemaps will be generated and uploaded to Sentry, so that you get readable stack traces in your Sentry issues.
For the SDK to be able to upload source maps to Sentry, you need to provide an auth token. You can pass an auth token directly via the authToken option:
next.config.mjsexport default withSentryConfig(nextConfig, {
// Specify the organization and project to upload source maps to
org: "example-org",
project: "example-project",
// Pass the auth token
authToken: process.env.SENTRY_AUTH_TOKEN,
});
Alternatively, you can set the SENTRY_AUTH_TOKEN environment variable:
Do not commit your auth token to version control.
.envSENTRY_AUTH_TOKEN=sntrys_YOUR_TOKEN_HERE
You can disable the custom sourcemap plugin as follows:
next.config.mjsexport default withSentryConfig(nextConfig, {
sourcemaps: {
disable: true,
},
});
Depending on your deployment setup, adding sentry/nextjs to your app may cause your source code to be visible in browser devtools when it wasn't before. (This happens because of the default behavior of webpack's source-map built-in devtool.) To prevent this, you can use hidden-source-map rather than source-map, which will prevent your built files from containing a sourceMappingURL comment, thus making sourcemaps invisible to the browser. To use hidden-source-map, add a sentry object to nextConfig above, and set the hideSourceMaps option to true:
next.config.mjsexport default withSentryConfig(nextConfig, {
hideSourceMaps: true,
});
If you find that there are some frames in your client-side stack traces that aren't getting source-mapped even when most others are, the issue might be that those frames are from files in static/chunks/ rather than static/chunks/pages/. By default, such files aren't uploaded because the majority of the files in static/chunks/ only contain Next.js or third-party code.
To upload all of the files and source maps, including ones from third-party packages, set the widenClientFileUpload option to true:
next.config.mjsexport default withSentryConfig(nextConfig, {
widenClientFileUpload: true,
});
You might notice that Sentry events are sometimes blocked by ad blockers. Ad blockers can be circumvented by using tunneling.
The Sentry Next.js SDK provides an easy way to set up tunneling for your application. Use the tunnelRoute option to provide the SDK a route to use to tunnel events to Sentry:
next.config.mjsexport default withSentryConfig(nextConfig, {
tunnelRoute: "/monitoring-tunnel",
});
Setting this option will add an API endpoint to your application that is used to forward Sentry events to the Sentry servers.
Complications when using tunnelRoute with Next.js Middleware
If the route configured with tunnelRoute is intercepted by your Next.js middleware, the client-side events recording will fail. You can exclude the tunnel route by adding a negative matcher to your middleware like this: (?!monitoring-tunnel)
Please note that this option will tunnel Sentry events through your Next.js application so you might experience increased server usage.
The tunnelRoute option does currently not work with self-hosted Sentry instances.
Learn more about tunneling in the troubleshooting section.
The SDK will automatically instrument API routes and server-side Next.js data fetching methods with error and tracing.
To disable the automatic instrumentation of API route handlers and server-side data fetching functions, set the autoInstrumentServerFunctions to false.
next.config.mjsexport default withSentryConfig(nextConfig, {
autoInstrumentServerFunctions: false,
});
With this option, under the hood, the SDK is using a webpack loader to wrap all your API route handlers and data fetching methods.
If the automatic instrumentation doesn't work for your use case, you can turn it off globally and choose to only wrap specific API route handlers or data fetching functions instead.
For API routes, use the wrapApiHandlerWithSentry function:
pages/api/*import { wrapApiHandlerWithSentry } from "@sentry/nextjs";
const handler = (req, res) => {
res.status(200).json({ name: "John Doe" });
};
export default wrapApiHandlerWithSentry(handler, "/api/myRoute");
For data fetching methods, use the following functions:
wrapGetInitialPropsWithSentryforgetInitialPropswrapGetServerSidePropsWithSentryforgetServerSidePropswrapGetStaticPropsWithSentryforgetStaticPropswrapErrorGetInitialPropsWithSentryforgetInitialPropsin custom Error pageswrapAppGetInitialPropsWithSentryforgetInitialPropsin customAppcomponentswrapDocumentGetInitialPropsWithSentryforgetInitialPropsin customDocumentcomponents
If you want auto-instrumentation to apply by default, but want to exclude certain routes, use the excludeServerRoutes option:
next.config.mjsexport default withSentryConfig(nextConfig, {
excludeServerRoutes: [
"/some/excluded/route",
"/excluded/route/with/[parameter]",
/^\/route\/beginning\/with\/some\/prefix/,
/\/routeContainingASpecificPathSegment\/?/,
],
});
Excluded routes can be specified either as regexes or strings. When using a string, make sure that it matches the route exactly, and has a leading slash but no trailing one.
To disable the automatic instrumentation of Next.js middleware, set the autoInstrumentMiddleware option to false.
next.config.mjsexport default withSentryConfig(nextConfig, {
autoInstrumentMiddleware: false,
});
You can set the automaticVercelMonitors option to automatically create Cron Monitors in Sentry if you have configured Vercel Cron Jobs.
Automatic instrumentation of Vercel cron jobs currently only works for the Pages Router. App Router route handlers are not yet supported.
next.config.mjsexport default withSentryConfig(nextConfig, {
automaticVercelMonitors: true,
});
If you want the Sentry SDK to be available in your server-side & not in client-side, you can simply delete sentry.client.config.js. This will prevent webpack from pulling in the Sentry related files when generating the browser bundle. Similarly, to opt out of server-side SDK bundling, you can simply delete the sentry.server.config.js and sentry.edge.config.js files. Make sure to remove any imports of these files from instrumentation.ts.
Set the disableLogger option to true to strip the Sentry SDK debug logger out of your client bundles, saving bundle size. Please note that this will effectively override and disable the debug option in your Sentry.init() calls.
next.config.mjsexport default withSentryConfig(nextConfig, {
disableLogger: true,
});
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").