Manual Setup

If you can't (or prefer not to) run the automatic setup, you can follow the instructions below to configure your application.

Copied
npm install --save @sentry/nextjs

If you're updating your Sentry SDK to the latest version, check out our migration guide to learn more about breaking changes.

Create three files in the root directory of your project, 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)
Copied
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 performance monitoring.
  // 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
});
sentry.server.config.(js|ts)
Copied
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",

  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  tracesSampleRate: 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
});
sentry.edge.config.(js|ts)
Copied
import * as Sentry from "@sentry/nextjs";

Sentry.init({
  dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",

  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  tracesSampleRate: 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
});

You can include your DSN directly in these three files, or provide it in either of two environment variables, SENTRY_DSN or NEXT_PUBLIC_SENTRY_DSN.

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
Copied
"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>
        {/* This is the default Next.js error component but it doesn't allow omitting the statusCode property yet. */}
        <NextError statusCode={undefined as any} />
      </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
Copied
"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>
  );
}

Create a Custom Next.js Error Page and call captureUnderscoreErrorException in your Error Page's getInitialProps method:

_error.tsx
Copied
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;

Use withSentryConfig to extend the default Next.js usage of webpack. This will do two things:

  • Automatically call SDK initialization code, at server start up and client page load.
  • Generate and upload source maps to Sentry, so that your stack traces contain readable code.

Include the following in your next.config.js or next.config.mjs:

next.config.(js|mjs)
Copied
// This file sets a custom webpack configuration to use your Next.js app
// with Sentry.
// https://nextjs.org/docs/api-reference/next.config.js/introduction

const { withSentryConfig } = require("@sentry/nextjs");

// your existing module.exports or default export
const nextConfig = {

  // Optional build-time configuration options
  sentry: {
    // See the sections below for information on the following options:
    //   'Configure Source Maps':
    //     - disableServerWebpackPlugin
    //     - disableClientWebpackPlugin
    //     - hideSourceMaps
    //     - widenClientFileUpload
    //   'Configure Legacy Browser Support':
    //     - transpileClientSDK
    //   'Configure Serverside Auto-instrumentation':
    //     - autoInstrumentServerFunctions
    //     - excludeServerRoutes
    //   'Configure Tunneling to avoid Ad-Blockers':
    //     - tunnelRoute
    //   'Disable the Sentry SDK Debug Logger to Save Bundle Size':
    //     - disableLogger
  },
};

const sentryWebpackPluginOptions = {
  // Additional config options for the Sentry webpack plugin. Keep in mind that
  // the following options are set automatically, and overriding them is not
  // recommended:
  //   release, url, configFile, stripPrefix, urlPrefix, include, ignore

  org: "example-org",
  project: "example-project",

  // An auth token is required for uploading source maps.
  authToken: process.env.SENTRY_AUTH_TOKEN,

  silent: true, // Suppresses all logs

  // For all available options, see:
  // https://github.com/getsentry/sentry-webpack-plugin#options.
};

// Make sure adding Sentry options is the last code to run before exporting
module.exports = withSentryConfig(nextConfig, sentryWebpackPluginOptions);

// If you're using a next.config.mjs file:
// export default withSentryConfig(nextConfig, sentryWebpackPluginOptions);

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:

Copied
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 an instance of SentryWebpackPlugin to the webpack plugins, 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.

To configure the plugin, pass a sentryWebpackPluginOptions argument to withSentryConfig, as seen in the example above. All available options are documented here.

If you choose to handle source map generation and uploading separately, the plugin can be disabled for either the server or client build process. To do this, add a sentry object to nextConfig above, and set the relevant options there:

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    disableServerWebpackPlugin: true,
    disableClientWebpackPlugin: true,
  },
};

Note that you'll also have to explicitly set a release value in your Sentry.init().

If you disable the plugin for both server and client builds, it's safe to omit the sentryWebpackPluginOptions parameter from your withSentryConfig call:

next.config.(js|mjs)
Copied
module.exports = withSentryConfig(nextConfig);

In that case you can also skip the sentry-cli configuration step below.

(New in version 6.17.1, will default to true in 8.0.0 and beyond.)

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.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    hideSourceMaps: true,
  },
};

Note that this only applies to client-side builds, and requires the SentryWebpackPlugin to be enabled. This option will default to true starting in version 8.0.0. See https://webpack.js.org/configuration/devtool/ for more information.

If you find that there are in-app frames in your client-side stack traces that aren't getting source-mapped even when most others are, it's likely because they 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, and are named in such a way that it's hard to distinguish between relevant files (ones containing your code) and irrelevant ones.

To upload all of the files in static/chunks/ anyway, add a sentry object to nextConfig above, and set the widenClientFileUpload option to true:

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    widenClientFileUpload: true,
  },
};

The SentryWebpackPlugin uses the Sentry CLI to manage releases and source maps, which can be configured in one of two ways - using a configuration file, or with environment variables - both of which are discussed below. For full details, see the CLI configuration docs.

If you choose to combine the two approaches, the environment variables will take precedence over values set in the configuration file. One common approach is to set sensitive data (like tokens) in the environment and include everything else in the configuration file added to your VCS.

The URL, organization, and project properties identify your organization and project, and the auth token authenticates your user account.

You can commit all the properties to your VCS, except the auth token. You can accomplish this by using the .sentryclirc file and including your auth token:

.sentryclirc
Copied
[auth]
token=sntrys_YOUR_TOKEN_HERE

Don't forget to ignore .sentryclirc in your version control system to prevent it from being leaked!

Alternatively, the source map upload can be configured using environment variables.

PropertyEnvironment variable
urlSENTRY_URL
orgSENTRY_ORG
projectSENTRY_PROJECT
authTokenSENTRY_AUTH_TOKEN

(New in version 7.8.0)

The @sentry/nextjs SDK is designed to run in browsers which support ES6 (and certain ES6+ language features like object spread). If you need to support older browsers, and have configured Next.js to down-compile your code, you can apply the same down-compilation to the injected SDK code by using the transpileClientSDK option in your Next.js config:

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    transpileClientSDK: true,
  },
};

(This assumes you are using the next.config.(js|mjs) setup shown above.)

(New in version 7.26.0)

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 in the sentry object in your next.config.js or next.config.mjs to provide a route the SDK will use to tunnel events to Sentry:

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    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.

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 performance monitoring.

(New in version 7.14.0)

To disable the automatic instrumentation of API route handlers and server-side data fetching functions, set the autoInstrumentServerFunctions to false.

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    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.

(New in version 7.14.0)

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/*
Copied
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 for getInitialProps
  • wrapGetServerSidePropsWithSentry for getServerSideProps
  • wrapGetStaticPropsWithSentry for getStaticProps
  • wrapErrorGetInitialPropsWithSentry for getInitialProps in custom Error pages
  • wrapAppGetInitialPropsWithSentry for getInitialProps in custom App components
  • wrapDocumentGetInitialPropsWithSentry for getInitialProps in custom Document components

(New in version 7.20.0)

If you want auto-instrumentation to apply by default, but want to exclude certain routes, use the excludeServerRoutes option in the sentry object in your Next.js configuration file:

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    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.

(New in version 7.31.0)

To disable the automatic instrumentation of Next.js middleware, set the autoInstrumentMiddleware option to false.

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    autoInstrumentMiddleware: false,
  },
};

(New in version 7.52.0)

You can set the automaticVercelMonitors option to automatically create Cron Monitors in Sentry if you have configured Vercel Cron Jobs.

next.config.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    automaticVercelMonitors: true,
  },
};

If you want the sentry to be available in your server side & not in client side, you can make your sentry.client.config.js empty. This will prevent webpack from pulling in the Sentry related files when generating the browser bundle. The same goes the opposite for opting out of server side bundle by emptying sentry.server.config.js.

You cannot delete the respective config files because the SDK requires you to have it.

(New in version 7.50.0)

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.(js|mjs)
Copied
const nextConfig = {
  sentry: {
    disableLogger: true,
  },
};
Help improve this content
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").