7 common Next.js errors and how to solve them

mangelosanto

Matt Angelosanto

Posted on August 23, 2023

7 common Next.js errors and how to solve them

Written by Kingsley Ubah✏️

Next.js is presently one of the fastest-growing web frameworks in terms of adoption. In addition to features like static site generation, server-side rendering, and file routing, the Next.js team continually adds new features to make building highly optimized and performant web applications super easy.

Despite the many benefits and features Next.js offers to developers, as with any framework, you might run into errors in your code during development. Next does a good job of logging helpful messages, but you might still find some errors hard to debug.

This article explores the causes and solutions of some common errors in Next.js, including:

Let’s jump right in.

1. Next.js hydration errors

One common error you’re likely to 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 does not match what was rendered on the server
Enter fullscreen mode Exit fullscreen mode

To fix the error, you need to check the markup throughout your application and ensure that 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>
  )
}
Enter fullscreen mode Exit fullscreen mode

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>
  )
}
Enter fullscreen mode Exit fullscreen mode

Keep in mind that 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.

2. Document or window object error

When you try to access the window object while the component is still mounting, Next.js will throw an error that the document or window is not defined. This error also occurs when you install and use a library that tries to access the window object before the component mounts.

Suppose that you have a home.js file in your Next.js application. Attempting to access the local storage will result in the window is not defined error:

const Home = () => {
  const saveSession = (event) => {
    window.sessionStorage.setItem("key", event.target.value)
  }   

  return (
      <div>
        <input
          type="text"
          id="message"
          name="message"
          onChange={saveSession}
          value={message}
        />
      </div>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

This is the same with third-party libraries. For example, let’s say you installed the swiperjs package and the library then tries to access the window object internally. Using swiperjs as demonstrated in the code below will also result in the same error:

import { Swiper } from 'swiperjs'

const Home = () => {
  return (
    <>
      <Swiper
        spaceBetween={50}
        slidesPerView={3}
        navigation
        pagination={{ clickable: true }}  
       >
        // Slides go here
      </Swiper>
    </>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

This error occurs because Swiper is rendered before it can access the window object. To resolve this error, you need to execute the code that accesses the browser’s window object inside the useEffect() Hook. That way, the code only executes after the component has been mounted.

Here’s how you’d rewrite the first example for it to work:

const Home = () => {
  const saveSession = (event) => {
    useEffect(() => {
      window.sessionStorage.setItem("key", event.target.value)
    })
  }    

  return (
      <div>
        <input
          type="text"
          id="message"
          name="message"
          onChange={saveSession}
          value={message}
        />
      </div>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

If you’re using a library that accesses the window object, you need to load the library only after the component has been mounted. For example, this is how you’d load Swiper to avoid the error:

const Home = () => {
  const [domLoaded, setDomLoaded] = useState(false);

  useEffect(() => {
    setDomLoaded(true);
  }, []);

  return (
    <>
      {domLoaded && (
        <Swiper
          spaceBetween={50}
          // ...
        >
          <div>Test</div>
        </Swiper>
      )}
    </>
  );
};

export default Home;
Enter fullscreen mode Exit fullscreen mode

3. Build failure due to webpack errors

After running the next build command to build your Next.js application, you might get an error message stating that the build failed because of webpack errors:

Cannot read property 'asString' of undefined

> Build error occurred
Error: > Build failed because of webpack errors
Enter fullscreen mode Exit fullscreen mode

Next.js v11 and newer use webpack 5 by default. However, this error only occurs with webpack 4.

To resolve the issue, you need to enable webpack 5 in your Next.js application. You can do this by adding the following setting in next.config.js:

module.exports = {
  // Add this:
  future: {
    webpack5: true,
  },
};
Enter fullscreen mode Exit fullscreen mode

4. API and slug-related errors

A large number of errors in Next.js are related to APIs and slugs. Next.js provides two APIs for data fetching — getStaticPaths and getServerSideProps. However, these functions can throw an error if not properly used.

Here's an error you might often get with the getStaticProps API:

Error: getStaticPaths is required for dynamic SSG pages and is missing for '/productsPage/[slug]'
Enter fullscreen mode Exit fullscreen mode

You get this error when you render a page on the server side with the SSG feature, but fail to define the getStaticProps function in the page’s component.

This is because Next.js requires the getStaticPaths function to build server-side rendered or statically generated pages that use dynamic routes. So, the solution is simply to add a getStaticPaths() function to the page component for /pageName/[slug].

Let’s see an example. In a hypothetical ecommerce store, the /pageName/[slug] page could show the details of a particular product.

In that case, you can use the getStaticPaths function to retrieve a list of all the available product slugs from a database, then return the list to be used for the [slug] parameter:

export async function getStaticPaths() {
  const res = await fetch('http://localhost/path/to/products')
  const products = await res.json()
  const slugs = products.map(post => product.slug)

  return {
    paths: slugs.map((slug) => ({ params: { slug } })),
    fallback: false
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Error when importing modules

When importing modules into your Next.js application, you might run into the Module not found error:

Module not found: Can't resolve 'fs'
Enter fullscreen mode Exit fullscreen mode

This means that Next.js is unable to locate the module specified in the error message. If you’re using a local module, then you need to specify its correct path. But if it's an npm or Yarn module, the error usually occurs because the module isn’t available on the client side.

One way to fix this issue is to ensure that all Node.js and server-related code is placed inside of the Next.js data-fetching APIs — getServerSideProps, getStaticPaths, or getStaticProps:

export function Home({ fileInfo }) {
  return (
    <div>
      {/* page content */}
    </div>
  );
}

export default Home;

export async function getServerSideProps(context) {
  const util = require('util');
  const tring = util.format(1, 2, 3);

  return {
    props: {
      fileInfo,
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

If that fails to resolve the issue, then you might want to cross-check that the letter casing of the file you’re attempting to import is correct. Here’s an example:

// components/MyComponent.js
export default function MyComponent() {
  return <h1>Hello</h1>
}
Enter fullscreen mode Exit fullscreen mode

When importing the above component, you need to use the exact letter case of the filename:

// pages/index.js

// This will not work
import MyComponent from '../components/Mycomponent'

// This will work
import MyComponent from '../components/MyComponent'
Enter fullscreen mode Exit fullscreen mode

Note that incorrect letter casing will only lead to Module not found errors in case-sensitive environments.

6. CORS error — Debugging Next.js API routes

The /pages/api directory is where you put all the files responsible for handling API requests, with the file name corresponding to the endpoint. Next.js then automatically maps these files to the /api/* URL, which you can access within the application via asynchronous API requests.

Once you deploy your app to the internet, the app will exist on a different origin. As a result, attempting to access the API endpoint will result in a CORS error as shown below:

Access to fetch at 'http://example.com/api/test' from origin 'http://localhost:3000' has been blocked by CORS policy
Enter fullscreen mode Exit fullscreen mode

To fix the CORS issue, you need to use CORS to handle cross-origin requests. Start by installing cors:

npm install cors
# OR
yarn add cors
Enter fullscreen mode Exit fullscreen mode

Once installation completes, you can import the library and use it to execute custom middleware just before the API’s response is received. Here’s an example where we set up the POST, GET, and HEAD methods for this endpoint:

// pages/api/test.js

import Cors from "cors";

const cors = Cors({
  methods: ["POST", "GET", "HEAD"],
});

function middleware(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 runMiddleware(req, res) {
  await middleware(req, res, cors);

  // Other API logic
  res.json({ result: result });
}
Enter fullscreen mode Exit fullscreen mode

With this code, we can make all four types of API requests to a different origin successfully without encountering the CORS error.

7. Catching all errors in your Next.js app

When creating your Next.js application, it’s important to catch all errors and make sure each of them is handled. The best way to do this is at the component level using the try...catch syntax.

In the following example, if any error is encountered while fetching data from the API, we log the error, render the built-in error page, and pass in a 503 status code:

import fetch from "isomorphic-fetch"
import Error from "next-error"

const Home extends React.Component {
  static async getInitialProps() {
    let products = [];

    try {
       const resp = fetch("https://my-store.com")
       products = await resp.json()
    } catch(err) {
       console.log(err)
    }

    return { products }
  }

  render () {
    const { products } = this.props

    if(products.length === 0) {
      return <Error statusCode={503} />
    }

    return (
     <div>
       {products.map((product) => {
         <h3 key={product.id}>{product.title}</h3> 
       })}
     </div>
    )
  }
}
Enter fullscreen mode Exit fullscreen mode

To learn more about catching and resolving errors in Next.js, check out our articles on testing and error handling patterns and troubleshooting a Next app with ESLint.

Conclusion

Next.js is growing in popularity and usage. But as with any other technology, an application built with Next.js isn’t safe from errors and issues.

By reading up on common errors in Next.js, the causes of these errors, and their respective solutions — as we covered in this article — you can optimize your web app and ensure that it performs as expected.


LogRocket: Full visibility into production Next.js apps

Debugging Next applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket Signup

LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your Next.js app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your Next.js apps — start monitoring for free.

💖 💪 🙅 🚩
mangelosanto
Matt Angelosanto

Posted on August 23, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related