How to Display a 404 Page in Next.js

Category
Next.js
Reading Time
0
 min
Date
July 26, 2025

Ever landed on a website and been greeted by a bland, uninspiring "404 Page Not Found" message? It's the digital equivalent of hitting a dead end in a maze, frustrating and unhelpful.

In Next.js, handling 404 pages feels easy and downright elegant. This framework has a knack for simplifying tricky tasks, and with the latest updates, it makes creating custom error pages feel like second nature.

Next.js automatically detects unmatched routes and serves up a 404 page, so developers don't have to sweat the small stuff. But what really stands out is how the framework separates functionality between its pages and app directories. If you're working in the app directory, not-found.js or not-found.tsx become your go-to for creating polished, personalized error pages. It's straightforward, and honestly, kind of fun.

Whether you're using static or dynamic routes, Next.js makes the entire process a breeze.

These improvements make life easier for developers, speed up iteration cycles, and improve the user experience. A thoughtfully crafted 404 page signals professionalism, offers a chance to redirect lost visitors, and helps keep them engaged.

It's a small detail that makes a big difference.

Setting Up Custom 404 Pages in Nextjs

Setting up custom 404 pages in Next.js is a breeze, and it's one of those small tweaks that can make a big difference for your app's user experience. Whether you need a global 404 page or route-specific ones, the process is simple and flexible.

Here's how to do it:

First, for a global 404 page, create a not-found.js or not-found.tsx file in the app directory. This file acts as the default handler for any unmatched routes in your app. Inside, define your component:

export default function NotFound() {
  return (
    <div>
      <h1>404 - Page Not Found</h1>
      <p>The page you are looking for does not exist.</p>
    </div>
  );
}

This ensures that any invalid URL your users stumble upon will gracefully show this page instead of a generic error message.

For more specific error handling, like nested route-specific 404 pages, you'll want to create not-found.js files within the dynamic route folders themselves. For example, if you've got a dynamic route like app/products/[id], drop a not-found.js file into that folder:

export default function ProductNotFound() {
  return (
    <div>
      <h1>Product Not Found</h1>
      <p>The requested product does not exist.</p>
    </div>
  );
}

This way, users navigating to an invalid product ID get a more context-aware message.

It's a thoughtful touch that your users will appreciate.

Your folder structure should look something like this:

app/  
├── not-found.js  
├── products/  
│   ├── [id]/  
│   │   ├── page.js  
│   │   ├── not-found.js  

Once your 404 pages are in place, you should definitely test them.

In development, use npm run dev and deliberately visit non-existent routes (like /non-existent-page or /products/non-existent-id).

For production, after running npm run build and npm start, repeat these tests to confirm consistent behavior.

And don't skip this step, ensuring your 404 pages work smoothly across environments demonstrates attention to detail, showing your users that every aspect of your app has been carefully considered.

Advanced Nextjs 404 Page Techniques

When it comes to advanced error handling in Next.js, the flexibility it offers with 404 pages is nothing short of impressive. The basics are great, and if you're building something innovative, you'll want a setup that goes beyond the cookie-cutter approach.

First up: the notFound() function. This little gem lets you programmatically trigger a 404 response right within your route components. Imagine you're fetching data for a dynamic route, and it turns out the requested resource doesn't exist.

With notFound(), you seamlessly render your custom 404 page while maintaining the current URL:

import { notFound } from 'next/navigation';

export default async function Page({ params }) {
  const data = await fetchData(params.id);
  if (!data) {
    notFound();
  }
  return <div>{data.content}</div>;
}

It's clean, efficient, and makes handling dynamic routes a breeze.

Then there's the not-found.js file convention. Drop this file in the app directory, and Next.js takes care of the heavy lifting for unmatched routes.

When you have many dynamic routes in a single folder, catch-all routes shine. A [...not_found]/page.js setup lets you neatly handle anything that doesn't match your expected paths, calling notFound() when needed.

For those working with nested routes, Next.js lets you go granular.

Place a not-found.js file inside a segment directory, say, app/blog, and voilà, you've got localized 404 handling specific to certain routes.

These techniques ensure smooth navigation and are a subtle way of showing users you've thought of everything.

It's attention to detail that sets exceptional apps apart.

purple and yellow abstract painting

Best Practices for Nextjs 404 Page Implementation

To wrap it all up, implementing a custom 404 page in Next.js is a straightforward yet impactful way to enhance both user experience and app reliability. By leveraging features like the not-found.js file, programmatic error handling with notFound(), and localized 404 pages for nested routes, you can ensure unmatched paths are managed with precision and style.

These tools simplify the development process, help you maintain brand consistency and keep users engaged even when they've strayed off the beaten path.

The latest Next.js routing conventions make handling 404 errors more intuitive than ever. Whether you're building a global error page or fine-tuning behavior for specific routes, the flexibility is there to match your app's unique needs.

And let's not forget: a polished 404 page serves as both a functional element and an opportunity to leave a lasting impression, guiding users back to where they need to be.

If you’re looking to create an app that’s fast, beautiful, scalable, and user-friendly, let us help you bring your vision to life.

Contact us today to kickstart your MVP development journey. We'll handle the technical heavy lifting so you can focus on what matters most, growing your startup.

Ready to Build Your MVP?

Your product deserves to get in front of customers and investors fast. Let's work to build you a bold MVP in just 4 weeks—without sacrificing quality or flexibility.