Error handling and logging
As we saw earlier, each route segment is a directory into we can put different files. We already created the page(.tsx|.jsx|.mdx) file, then Next.js 15 created a default layout file for us, the third file we will now create is an error page
How this works is that Next.js will automatically wrap the children of your page with a React Error Boundary, meaning that when an error gets thrown in a page, then the error boundary will contain it and then use the error file that is the closest (either an error file that is in the same directory as the page itself or a parent directory), that error page can do different things with the error, obviously it can display an error message to the user but you can also use it to do other things like save the error in your database or send a request to your logging service
Let's create our first error file inside of our /app
directory, and let's use the example from the Next.js documentation like so:
Lines 5 to 8: we create a Typescript interface for the props our error boundary
Lines 10 to 13: a Next.js error boundary will give you two useful things, the error itself and a function that can rerender the segment in which the error occurred
Lines 23 to 28 there is the second feature of this component, a button
which will trigger the reset
function we got from the component props (line 10), this function provided by Next.js will attempt to rerender the segment that triggered an error, this is helpful if the error was caused by something that occurs sporadically and might allow the user to continue
As you can see, the Next.js documentation example uses a useEffect()
function (lines 13 to 16) and inside of it we use a console.log
to print an error in the console of the browser, but what happens if the error is getting triggered on a user's computer, then we won't know about it. This is why in the next chapter, we will use a third-party service called Sentry.io to do the logging for us (of course if you prefer you can also develop and run your logging service instead)
Using Sentry.io to log errors
In this chapter, we will use Sentry.io (which has a free plan for side projects) to add error logging to the Next.js error file we just created
We will use the Sentry.io Wizard tool to install the Sentry.io SDK for Next.js or you can follow their manual setup tutorial (if you prefer a manual installation).
Sentry.io account & first project
First, you need to have or create an account on Sentry.io (if you need help with that step, check out my chapter Create a Sentry account (sign up) in the Sentry.io post)
Now we need to create a new project on Sentry.io (if you need help with that step, check out my chapter Create a Sentry.io project in the Sentry.io post)
Before using the wizard, I recommend committing your latest changes (if you haven't already) and doing a last sync before launching the sentry wizard, as the Sentry Wizard will add and edit some existing files. This way you will be able to see (using a git diff after the wizard is done) which new files the Sentry Wizard has added, and also see what got changed in existing files like the next.config.(mjs|ts) file
Next.js 15.x canary (optional)
If you don't use the latest stable version of Next.js 15.x but prefer to use a canary version, then attempting to add the latest version of Sentry for Next.js will likely result in a dependency error:
You can bypass this error by using the overrides in your package.json, here is an example of what your package would look like with an overrides for Next.js 15 canary:
Lines 22 to 24 we add an overrides that will tell npm that it should use this Next.js version instead of the one it finds in the peer dependencies for Sentry and potentially other packages as well
In the package.json I used the canary tag, if you want to use an exact version you can use the npmjs next versions page or you have a look inside of their next package.json.
When you update your exact canary version, make sure that you update both Next.js versions, the one in your dependencies and the one you use in the overrides
Sentry Installation Wizard
Or, if you prefer to use the wizard without sending telemetry data to sentry.io (usage statics and crash reports), then add the --disable-telemetry
option to the command, like so:
Wizard Q&A
First, you will get asked if you accept installing the sentry wizard npm package. Press y
to accept and press Enter
to move on
After the installation, the wizard will automatically get launched, and it will start asking you questions about your setup preferences:
Are you using Sentry SaaS or self-hosted Sentry? You probably want to choose Sentry SaaS (sentry.io) like I did (but if you are a company and need a custom solution, then you might want to look at the hosted version), then press Enter
.
Do you already have an account? chose Yes (if you did follow the previous chapter or already had an account before), then press Enter
(or choose No if you have no account yet and follow the account creation process)
Then, the sentry wizard will ask you to log in, which will open the sentry login page in your default browser. Log into your account, then go back to your terminal.
Select your Sentry project, choose your Sentry Project from the list (when using the wizard, Sentry will have automatically created a project for the SDK you chose earlier for you; if, however, you don't see a Project listed here, you can check out the Create a Sentry.io project chapter to create a project first)
Now, Sentry will install the latest Sentry SDK for Next.js.
Do you want to route Sentry requests in the browser through your NextJS server to avoid ad blockers? Sentry wants to know if it should route its requests through your Next.js server. By doing so, Sentry attempts to bypass the block lists of adblocker addons that are installed in some browsers. This means Sentry will first send the client-side requests to a URL on your server, and then your server will forward the request to the Sentry API. I personally chose Yes as I want to increase the chance of getting bug reports but feel free to answer No (if for example, you don't want to have the extra traffic, on your server backend, that this redirect will cause)
Do you want to enable React component annotations to make breadcrumbs and session replays more readable? Next Sentry is asking if we want to use the feature called React component annotations which attempts to use component names in reports instead of more cryptic selectors, I think this is a nice feature, so I selected Yes, if you already use Sentry.io and don't want to change how bug reports work, then leave it on No, you can always turn it on/off via the configuration later if you want
I turned React component annotations on and then noticed that my react-three-fiber animation had stopped working, this is because React component annotations adds data attributes to components which React Three Fiber does not like, and which then creates bugs which print the following in your console:
TypeError: Cannot read properties of undefined (reading 'sentry')
So if you plan on using React Three Fiber then you should answer to this question with NO, to learn more about this problem and how to disable React component annotations manually in the configuration have a look at the Sentry React Component Annotation(s) can be problematic chapter
Do you want to create an example page chose YES (we will later use it to test the Sentry setup, and then we will delete it)
Are you using a CI/CD tool to build and deploy your application? chose YES (if you are using Vercel, GitHub actions, or any other CI/CD deployment tool); If you do NOT use one, choose NO)
The Sentry.io Wizard will give you a SENTRY_AUTH_TOKEN string if you choose yes. If you use a CI/CD for your deployments, copy the token, and save it in a secure location, you will need this token later if, for example, you set up a custom GitHub action. You will want to add that token environment variable to your GitHub secrets. If you use another CI/CD service, check out their documentation to learn how to use that token to upload source maps to Sentry automatically. If using Vercel, you can use the Sentry integration for Vercel, which will set the Vercel environment variables for you, or if you prefer you can add the token manually to your environment variables using the Vercel environment variables interface.
CI/CD tools can authenticate themselves to Sentry.io using the SENTRY_AUTH_TOKEN environment variable and then use the Sentry.io API to automatically upload the source maps of your build to Sentry.io. Later, if there is a bug report on Sentry.io, it will be able to use the source maps instead of the minified build files to show you where the error occurred.
Did you configure CI as shown above? chose YES
That was the last question:
Successfully installed the Sentry Next.js SDK!
After answering all questions, the Sentry SDK will edit your next.config.mjs to add the withSentryConfig Sentry configuration, and it will have added several sentry.*.config files (to the root of your project) that contain environment-specific configurations, it will also create some other files depending on what answers you gave, like a page.tsx that we can now use to test the setup
If you use Vercel for your deployments, then you don't need to set the SENTRY_AUTH_TOKEN yourself; you can use the Sentry integration for Vercel, which will set the Vercel environment variables for you, I recommend you do that now, as all you need to do is click on the Add integration button, and then continue with the tutorial
Update Sentry SDK version (to use alpha or beta) (optional)
If you use the wizard it will always use the latest version of Sentry for Next.js
If you are feeling adventurous, you could try out the latest alpha or beta versions, to know what versions are currently available I recommend having a look at the Sentry for Next.js version page and check out what the latest versions are
Sentry for Next.js has a next branch that is similar to a canary in Next.js, if you want to install that version (instead of the latest that the wizard installed), then use the following command:
This will replace the current version of Sentry for Next.js with a more up to date but also more experimental version
be careful when you chose what version you install as there is not always an alpha or beta available, sometimes the newest beta or alpha that is tagged with next (on npmjs) will actually be older than the version tagged as latest
Sentry configuration
Sentry.io can be customized a lot and has several places to change the default configuration.
The main part of the Sentry for Next.js configuration is in your next.config.ts
file (which is in the root of your project):
Lines 25 to 66: the Sentry wizard has updated your next.config.ts
based on the answers you gave to the wizard questions (I formatted mine (in VSCode, you can right click and then select Format Document)
Now is a good time to commit the updated next.config.ts
(and other changes the wizard did)
By default, the options that the wizard set for us are good enough. As soon as you have the time, I recommend checking out the Extend your Next.js Configuration Sentry.io documentation, which explains what each option does
Sentry React Component Annotation(s) can be problematic
To enable Sentry reactComponentAnnotation configuration option is usually a good idea as it makes reports more readable by using component names instead of long selectors
To make this feature happen Sentry needs to add a data attributes to components, this does usually not pose a problem except sometimes the Sentry Annotations on third party components will cause an error in those third party tools
I have a more detailed explanation about annotations and the problems that can occur in my Sentry Post
The solution to these problems is to disable the feature and wait for the Sentry team to fine tune the feature (which is quite young) and fix annotations bugs (I have linked to some tickets in my Sentry post, you may want to subscribe to them if you want to keep track of fixes)
Sentry does not (yet) support Turbopack
If you try to use Turbopack with Sentry you will get the following error:
As of now (dec. 2024) there is no workaround available for this, you need to make a choice and either not use Turbopack or use Turbopack but then Sentry will not get loaded in development (production builds are not impacted as Next.js does NOT (yet) use Turbopack for production builds)
In the meantime if you are interested in seeing how the Sentry JS SDK support for Turbopack progresses, then I recommend subscribing to their "Turbopack Support" issue #8105
I assume the first Sentry SDK release that will be fully compatible with Turbopack will be v9 (this is an assumption)!? But before that happens there is a quite long list of Sentry javascript SDK v9 tasks, the Turbopack changes are related to withSentryConfig
The instrumentation file
Next.js has added support for a new instrumentation which has the goal to improve the integration of monitoring and logging tools into Next.js
Sentry wizard will have created such a instrumentation.ts
file for us, with the following content:
Sentry Client Configuration file
Another file that got added to the root of our project is sentry.client.config.ts
, which is used to configure Sentry.io for client components. Check out the Next.js SDK Configuration Options documentation for more details about each option. We will slightly modified the Sentry configuration to this:
Lines 7 to 8: we added two variables for the replaysOnErrorSampleRate we set it to zero by default to not produce replays when not in production and we set the tracesSampleRate to 0.1, meaning we want to limit the amount of traces that get recorded (and sent to sentry) to 10%
Lines 10 to 12: we added a check to verify if the current environment is production and if it is we tell Sentry to always make a replay if there is an error (be careful with this option, in the free plan you only have 50 replays per month, which is why I only turn it on in production, also in development it is usually the developer that triggers the error so there is not really a need for a replay)
Lines 14 to 16: we disable the traces in development (this is to ensure no performance metrics are getting calculated when the app is running on a local computer, to check local performance it is preferred to use the developer tools), you may want a lower or higher value depending on what plan you are on and then check if you reach your limits or not and then adjust over time
Lines 22 and 27: we replace the default sentry values with our replaysOnErrorSampleRate and tracesSampleRate variables
Line 31: we set the replaysSessionSampleRate to zero (related to the changes we did line 10 to 12)
Line 42: we pass the environment to Sentry, meaning Sentry will know if the environment is preview or production (that value is based on the Vercel environment on which Next.js got deployed)
If you copy paste the sentry.client.config.ts
above into your project make sure you update the YOUR_SENTRY_DSN_URL placeholder with your own Sentry DSN
sentry.edge.config.ts
are the options for when Next.js uses the Vercel Edge Network. I kept that file, but feel free to adjust any values to fit your use case.
sentry.server.config.ts
is again similar to the previous two, just this one is specifically for Next.js server-side options. I also kept this file as is
There is, however, one option in the server configuration that is commented out (by default) that you might want to consider. The option lets you use the Spotlight js package by Sentry. If you're going to use it, I recommend checking out the documentation to install and setup Spotlight in a Next.js project
Sentry Next.js example page
Next, as suggested by the wizard at the end of the installation process, it is recommended to start the development server using the npm run dev
command, and then we visit the Sentry example page in our browser at http://localhost:3000/sentry-example-page
On that page, hit the Throw Error! button and then click on the link just below to visit your Sentry projects issues page
Now wait for the backend and frontend errors to appear (this can take a few minutes, which is a good time to refresh your cup of coffee โ (or whatever beverage you prefer))
As soon as the two errors appear, feel free to click on them and have a look at what error logging on Sentry.io looks like
Before we commit/sync all the changes Sentry.io did in our project, delete the app\sentry-example-page\
folder, including the page.jsx
example page, and then also delete the app\api\sentry-example-api\
folder including the route.js
API example route file that Sentry.io created to test the error logging, you will not need them anymore.
Error page with Sentry error logging
Now that Sentry.io is set up, we can modify the error file we created earlier, like so:
Line 3: we import the Sentry SDK
Lines 17 to 18: we replace our console.error (inside of the useEffect()
) with the Sentry.io captureException logging function
Handling global errors
The Sentry.io wizard we just used has created a Next.js app/global-error.jsx
file for us
The Next.js documentation explains well why this file is essential:
The root app/error boundary does not catch errors thrown in the root app/layout or app/template component.
To specifically handle errors in these root components, use a variation of error.js called global-error.js located in the root
/app
directory.global-error is the least granular error UI and can be considered "catch-all" error handling for the whole application.
same as for the warnings above, if you used the current wizard with Next.js and a typescript configuration file then the wizard will have created a app/global-error.jsx
file, if this is your case then delete the app/global-error.jsx
and create a new app/global-error.tsx
file, then insert the code as shown below
We will update the global-error file Sentry just created, and add a slightly different UI using the same reset button we added to the regular error page instead of using the Next.js built in NextError component, the final version looks like this:
Line 3: we import the Sentry SDK
Lines 17 to 18: we replace our console.error (inside of the useEffect()
) with the Sentry.io captureException logging function
The global error handling file will handle root layout errors and act as a catch-all for app errors
Time to save, commit, and sync
Congratulations ๐ you now have error handling and logging for pages as well as global error handling in your project
If you liked this post, please consider buying me a coffee โ or sponsor โค๏ธ me on GitHub, as it will help me create more content and keep it free for everyone