Are you struggling with handling errors in Next.js applications and trying to make sense of the Vercel logging? Imagine this: you've poured your effort into developing an innovative web application, only to be defeated by Next.js errors. This article is precisely what you need to navigate through NextJS errors.
Alerty's NextJS logging solution is your go-to tool for mastering error handling in Next.js. This logging tool helps you achieve your goal of effectively managing errors in your applications and offers robust insights into improving your workflow.
Next.js is a popular React framework for building server-rendered and statically generated web applications. In the process of developing and running a Next.js application, you may encounter various types of Next.js errors. These errors can range from minor syntax errors to more critical runtime errors. Understanding these errors is crucial for effective troubleshooting and resolution.
Next.js errors are divided into two categories:
Syntax errors occur when the code is not written correctly during the compilation of the Next.js application. The build process reports these errors, usually due to incorrect code syntax. Common syntax errors include:
Runtime errors, on the other hand, occur when the application is running and result from issues outside the build process. These errors can be caused by a wide range of issues, from invalid data in a database to issues with third-party APIs.
The framework provides an error-handling mechanism to aid in troubleshooting Next.js errors. When an error occurs during the build process or runtime of a Next.js application, it is linked to a specific line number in the source code. This makes it significantly easier for developers to promptly identify and fix the error.
Next.js includes a comprehensive error reporting system that generates informative error messages, helping developers understand the cause of the error. By providing detailed information about the error, including its type and what caused it, Next.js empowers developers to resolve issues efficiently.
Next.js errors can occur at various stages of the application development and runtime. Syntax errors happen during the build process due to incorrectly written code, while runtime errors occur when the application runs.
Next.js offers a robust error-handling mechanism that includes informative error messages linked to specific lines in the source code. This makes it easier for developers to troubleshoot and fix issues efficiently. Developers can build more robust and reliable applications by understanding the different types of Next.js errors and leveraging the framework's error-handling capabilities.
To handle errors in Next.js, you need some basic knowledge of Next.js concepts. Below are the prerequisites you should have to get the best out of handling these errors:
1. Basic knowledge of JavaScript
2. Basic knowledge of React and Next.js
3. Basic knowledge of testing JavaScript libraries and frameworks
Alerty is a cloud monitoring service for developers and startups, offering:
It helps developers identify and fix issues. It supports technologies like:
Alerty monitors databases such as Supabase, PostgreSQL, and RDS, tracking key metrics like CPU usage and memory consumption.
Catch issues before they affect your users with Alerty's NextJS logging tool today!
Middleware enables the execution of code before the completion of a request, and based on the incoming request, it modifies the response sent to the user by:
One error you could encounter when working with middleware in Next.js is
This error usually happens when you’re using Next.js with a custom server, and you did not explicitly specify the server host URL in your configuration; If you are using a mono repo build system like Nx, you’d also likely experience this error as tools like this one create a custom server for you behind the scene.
You can quickly fix this error by specifying the hostname in your server configuration file. If you use NX, you can modify the serve options in your project configuration file (project.js). In other words, you modify this file to look like this.
"serve": {
"executor": "@nrwl/next:server",
"defaultConfiguration": "development",
"options": {
"buildTarget": "test-nx:build",
"dev": true,
"port": 4200,
"hostname": "localhost"
},
. . .
}
In rare cases where your middleware code is not triggered at all, this may have happened due to the incorrect placement of your middleware file.
In older versions of Next.js, you create your middleware file as _middleware.js in the /pages directory. The latest versions of Next.js require that you save this file as middleware.js on the root folder, i.e., at the same level as the /pages directory.
With this new change, your file structure should look like this.
.
├── . . .
├── pages
│ └── index.js
├── public
├── middleware.js
└── . . .
SyntaxErrors in Next.js occur when the code has incorrect syntax or structural issues. These Next.js errors can prevent your application from running properly. Understanding and fixing these errors is essential for writing clean and error-free Next.js code. These errors are usually caught at build time and look like:
Common Next.js errors include:
How to resolve:
Next.js is shipped with the getStaticPaths and getServerSideProps API for data fetching; They occasionally throw errors when used incorrectly.
One of these errors, specifically with the getStaticProps API, is:
error - Error: getStaticPaths is required for dynamic SSG pages and is missing for '/pageName/[slug]'
This error occurs when a dynamic page is rendered on the server side using the Static Site Generation (SSG) feature in next.js. Still, the page's component does not define the getStaticPaths() function, which is a required part of the Next.js API for building server-side rendered (SSR) or statically generated (SSG) pages that use dynamic routes.
How to resolve:
Add a getStaticPaths() function to the page component for /pageName/[slug] to fix this error.
For example, if the page at /pageName/[slug] is meant to display information about a blog post, the getStaticPaths function could fetch a list of all the available blog post slugs from a database and return them as the possible values for the [slug] parameter.
export async function getStaticPaths() {
// fetch list of available slugs from a database
const res = await fetch('http://localhost/path/to/blogs')
const posts = await res.json()
const slugs = posts.map(post => post.slug)
// return the possible values for the [slug] parameter
return {
paths: slugs.map((slug) => ({ params: { slug } })),
fallback: false
}
}
It is also worth mentioning that all the Next.js data fetching APIs can only be used inside page components, and will not work outside regular components.
Another common error in Next.js is: Module not found: Can’t resolve ‘moduleName’, e.g.
This error usually occurs when you import a module that is not accessible by Next.js. In the case of the fs module, it is simply because the module is not available on the client side, and you or a third-party package tried to access it.
How to resolve
You can resolve this error by keeping all Node.js/server-related code inside of Next.js data fetching APIs—getServerSideProps, getStaticPaths, or getStaticProps.
export function Index({ fileInfo }) {
return (
<div>
{/* page content */}
</div>
);
}
export default Index;
export async function getServerSideProps(context) {
const fs = require('fs');
let fileInfo = fs.readFileSync('path/to/sample.txt');
return {
props: {
fileInfo,
},
};
}
In cases where the error had occurred because of a package you imported and not because you’re explicitly trying to access a Node.js module, you can modify your Next.js configuration file (next.config.js) to include an entry for webpack like this.
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
webpack: (config, { isServer }) => {
if (!isServer) {
config.resolve.fallback = {
fs: false,
};
}
return config;
},
};
module.exports = nextConfig;
In this code, the isServer property of the options object is checked to determine if the current build is for the server or the client. If the build is not for the server (i.e., if isServer is false), then the fs module is added to the fallback list in the resolve section of the webpack configuration.
This means that when webpack encounters an import for the fs module, it will not attempt to resolve the import, and the fs module will not be bundled with the application. This allows the fs module to be loaded at runtime on the server-side, but not on the client-side. If you’re not using Node.js modules and still get the module not found error, ensure the module has been installed and imported properly. There may be a casing error, so double-check that.
Next.js allows users to create REST API endpoints by placing files with the desired endpoint names inside the /pages/api directory. These endpoints are then mapped to the /api/* URL and can be accessed from within the application by making asynchronous requests.
Once your application has been deployed and you try to access the API endpoint from a different origin, you get the cors error like the one below. Access to fetch at 'http://example.com/api/hello' from origin 'http://localhost:3001' has been blocked by CORS policy ...
We can fix this error by leveraging the popular cors package to enable cross-origin sharing before our API route sends its response. First, we have to install the cors package.
npm install cors
# OR
yarn add cors
After that, we can import this package to run custom middleware before the API route sends its response, enabling the preferred method for the specific endpoint; for example, we can enable the POST, GET, and HEAD methods for this endpoint.
// pages/api/hello.js
import Cors from "cors";
const cors = Cors({
methods: ["POST", "GET", "HEAD"],
});
function runMiddleware(req, res, fn) {
return new Promise((resolve, reject) => {
fn(req, res, (result) => {
if (result instanceof Error) {
return reject(result);
}
return resolve(result);
});
});
}
export default async function handler(req, res) {
await runMiddleware(req, res, cors);
// Other API logic
res.json({ foo: "bar" });
}
You should stop experiencing cors errors once you have your API designed like this.
One of the most common errors in Next.js is the document/window not being defined. Why does it happen? This error typically appears when you or an installed package try to access the browser’s window objects directly in a page component, and Next.js will throw this error because the window object is not yet available while a component is still mounting.
Say we have a sample index.js page in our Next.js application and try to access the browser's localStorage, as shown below; we’ll get the window is not defined error.
const Index = () => {
window.localStorage.foo = "bar";
return (
<>
<div>
<h1>Hello world!</h1>
</div>
</>
);
};
export default Index;
There are different approaches to resolving this error; one straightforward option is to simply employ react’s useEffect() hook to execute the code block that requires the browser’s window object so that the code is only executed when the page component has been mounted.
import { useEffect } from "react";
const Index = () => {
useEffect(() => {
window.localStorage.foo = "bar";
}, []);
return (
<>
<div>
<h1>Welcome to my Blog!</h1>
</div>
</>
);
};
export default Index;
One common error you’ll likely encounter in both Next and React apps is the hydration error. Hydration errors result from a mismatch between server- and client-rendered markup and differences in component states.
Specifically, Next.js hydration errors arise when you wrap your components or HTML elements with an improper tag. A common example is when you have a p tag wrapping your divs, sections, or other elements.
The exact error message you’ll get is:
Hydration failed because the initial UI did not match what was rendered on the server
How to resolve:
You need to check the markup throughout your application and ensure you’re not wrapping elements or custom components with improper tags.
For example, the following component will result in a Next.js hydration error because we wrapped the div element inside the paragraph:
import Image from 'next/image'
export const ErrorComponent = ()=>{
return(
<p>
<div>Don't do this!</div>
<Image src='/logo.jpg' alt='' width='40' height='40'/>
</p>
)
}
Rather, use the right “wrapper” elements — e.g. div, section, main, etc. — to wrap your content:
export const CorrectComponent = ()=>{
return(
<div>
<div>Do this instead</div>
<Image src='/logo.jpg' alt='' width='40' height='40'/>
</div>
)
}
Some third-party components, such as those from MUI, may use the <p> tag as a top-level element. In such cases, you’ll need to wrap the component inside something semantic to avoid the error, like a <div> or <section>.
Properly arranging your HTML will greatly reduce the likelihood of encountering the hydration error in your Next app, but it’s not the only cause. You can also encounter the error after importing and running certain packages, as we will explore in the next section.
This error occurs when your code tries to access a variable that is not defined. It looks like:
How to resolve:
Type errors occur when a value is not of the expected type. An example message might be:
How to resolve:
Environmental variable errors usually occur if a necessary variable is missing or misconfigured. An example message might be:
How to resolve:
Following the best practices for error handling is important to effectively handle errors in your Next.js applications and provide a seamless user experience.
Error boundaries in Next.js allow you to catch errors within a component tree and display a fallback UI instead of crashing the entire application. You can isolate and handle errors gracefully by wrapping your components with error boundaries.
Next.js allows creating custom error pages displayed when an error occurs. This user-centric approach allows you to provide a more user-friendly and informative error message tailored to your application's design and branding. By creating custom error pages, you are directly contributing to improving the overall user experience and providing clear instructions on what to do next.
Logging and monitoring are essential for error tracking and debugging. By implementing logging mechanisms, you can capture and store detailed error information, including stack traces, request data, and user actions. With their proactive nature, monitoring tools can help you identify patterns and trends in errors, allowing you to stay ahead of potential issues and improve the stability of your Next.js app.
If your data fetch fails, it’s essential to show users an informative error message. Using the catch method combined with async/await, we encapsulate the failure scenario neatly and can define a specific reaction to it. Handling errors robustly and elegantly can help prevent mediocre user experiences. It also allows developers to debug effectively, resolving these errors quicker.
To maintain consistency and improve maintainability, consider creating a centralized error-handling module. This module can contain custom error classes, utility functions for handling errors, and a consistent error response format. By following these best practices for error handling in Next.js, you can ensure that your applications are robust, reliable, and user-friendly.
Alerty, a cloud monitoring service tailored to developers and early-stage startups, offers a comprehensive suite of monitoring tools to improve application performance, database monitoring, and incident management. This innovative platform supports a wide array of technologies, such as:
Alerty is not limited to application monitoring alone; it can also closely monitor databases like Supabase, PostgreSQL, and RDS, tracking crucial metrics such as CPU usage and memory consumption. By utilizing AI, Alerty simplifies the initial setup process, providing an affordable monitoring solution compared to other competitors.
Alerty aims to catch performance issues before they impact end-users. By providing quick incident management, it offers developers a streamlined approach to rectifying potential problems promptly. One of the standout features is Real User Monitoring (RUM), a technology that tracks user interactions with the application, allowing developers to gain insights into user behavior and performance metrics.
One of the key features of Alerty is its Universal Service Monitoring, which covers an extensive array of dependencies including:
This monitoring ensures that all critical services your application relies on remain operational and perform at optimal levels. By integrating with Vercel, Alerty is uniquely positioned to help developers catch and rectify potential NextJS errors before they impact users.
Alerty's NextJS logging tool is valuable for developers and small teams looking to monitor their applications efficiently. Alerty provides developers with a comprehensive solution to catch and resolve any issues before they impact the end-user experience, such as: