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.js
const { 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
// Learn more at
// https://docs.sentry.io/platforms/javascript/configuration/options/#traces-sample-rate
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
// Learn more at
// https://docs.sentry.io/platforms/javascript/session-replay/configuration/#general-integration-configuration
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.ts
import * 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.ts
import * 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.tsx
import * 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.mjs
export 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.
.env
SENTRY_AUTH_TOKEN=sntrys_YOUR_TOKEN_HERE
You can disable the custom sourcemap plugin as follows:
next.config.mjs
export 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.mjs
export 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.mjs
export 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.mjs
export 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.mjs
export 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:
wrapGetInitialPropsWithSentry
forgetInitialProps
wrapGetServerSidePropsWithSentry
forgetServerSideProps
wrapGetStaticPropsWithSentry
forgetStaticProps
wrapErrorGetInitialPropsWithSentry
forgetInitialProps
in custom Error pageswrapAppGetInitialPropsWithSentry
forgetInitialProps
in customApp
componentswrapDocumentGetInitialPropsWithSentry
forgetInitialProps
in customDocument
components
If you want auto-instrumentation to apply by default, but want to exclude certain routes, use the excludeServerRoutes
option:
next.config.mjs
export 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.mjs
export 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.mjs
export 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.mjs
export 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").