• Homeright arrow
  • Blogright arrow
  • Creating a Custom 404 Page in Next.js
Feature

Creating a Custom 404 Page in Next.js

In the faster world of web development, Next.js has introduced many new features that simplify your web experience. Such a feature is handling unmatched routes in your application. Next.js has added a simple, straightforward forward and developer-friendly process for creating a custom 404 page. In this post, I'll explain how to make a custom 404 error page that detects any mismatched URLs in your upcoming application. Later we will discuss the deeper functionalities of the error page in Next.js.

Create A Next.js App

The first and foremost step, to begin with, is creating a Next.js App. Use the following command to create a next.js app.

npx create-next-app@latest app-name

As it is not an article on creating the next.js app, we will not discuss it in detail. If you want to read it in detail follow the link.

Add not-found.jsx

Whenever we go to any unmatched route, next.js takes us to a default 404  page. This will look like the following image.

creating-a-custom-404-page-in-nextjs

However, we can easily customize this. All you have to do is create a not-found.jsx file in the app folder and it will automatically manage requests to a URL that doesn't have a corresponding route in your app. Let’s create a not-found.jsx file inside your app directory. Here's a basic markup that can be used in this file:

import Link from "next/link";
const NotFound = () => {
return (
<section className="mb-150 pt-[200px]">
<div className="container mx-auto">
<div className=" text-center">
<h1 className="from-0 to-primary/0 bg-gradient-to-b from-[red] to-90% bg-clip-text text-[140px] font-bold leading-[1] text-transparent dark:text-transparent">
404
</h1>
<p className="text-2xl font-semibold -mt-16">Error</p>
<h2 className="mb-9 text-[64px] font-bold leading-[1.22]">
Oops! <br />
Page Not Found
</h2>
<p className="mb-8 text-xl">
This page doesn’t exist or was removed! <br />
We suggest you go back to home.
</p>
<Link
href="/"
className="bg-gray-800 py-5 px-6 rounded-xl"
>
Go Back-Home
</Link>
</div>
</div>
</section>
);
};
export default NotFound;

You can style the components just like the other next.js components. I have used Tailwind here to style the file. You can read more about setting tailwind CSS on your site on this link

Note:  You can pass over whatever message you want inside the not-found.jsx file. I have added these codes to give examples only. 

After successfully adding these codes, run your build process with

npm run dev.

Your site will be opened on localhost:3000. Now, try to visit any unmatched route within your app and it should redirect you to the newly not-found.jsx component. And it should look like this:

creating-a-custom-404-page-in-nextjs


Data Fetching on not-found.jsx

By default, not-found.jsx is generated through the server as it is a Server Component. Thus, You can use an async function to fetch and display data. A simple example is attached below:

import Link from 'next/link'
import { headers } from 'next/headers'

export default async function NotFound() {
const headersList = headers()
const domain = headersList.get('host')
const data = await getSiteData(domain)
return (
<div>
<h2>Not Found: {data.name}</h2>
<p>Could not find requested resource</p>
<p>
View <Link href="/blog">all posts</Link>
</p>
</div>
)
}

Use not-found.jsx as Client Components

Though not-found.jsx is a server component, we can easily transform it into a client component. If an error with the path name needs to be shown, you have to convert it into client components by declaring “use client” and using Client Component hooks like usePathname to display content based on the path. A simple example is attached below:

"use client";
import Link from "next/link";
import {usePathname} from "next/navigation";


const NotFound = () => {
const pathname = usePathname();
return (
<section className="mb-150 pt-[200px]">
<div className="container mx-auto">
<div className=" text-center">
<h1 className="from-0 to-primary/0 bg-gradient-to-b from-[red] to-90% bg-clip-text text-[140px] font-bold leading-[1] text-transparent dark:text-transparent">
404
</h1>
<p className="text-2xl font-semibold -mt-16">Error</p>
<h2 className="mb-9 text-[64px] font-bold leading-[1.22]">
Oops! <br />
{pathname} Page Not Found
</h2>
<p className="mb-8 text-xl">
This page doesn’t exist or was removed! <br />
We suggest you go back to home.
</p>
<Link
href="/"
className="bg-gray-800 py-5 px-6 rounded-xl"
>
Go Back-Home
</Link>
</div>
</div>
</section>
);
};
export default NotFound;

Now, when you go to an unmatched route such as localhost:3000/error, you should have seen the following error:

creating-a-custom-404-page-in-nextjs

not-found.jsx in Sub Folder

We can also add separate not-found.jsx for each segment route. For example:

  • create products folder
  • Inside it create another [id] folder
  • Now create a page.jsx file.

Your folder structure should look like this:

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

Now add the following codes to the page.jsx file:

import {notFound} from "next/navigation";
export default function Products({params}) {
const {id} = params;
if (id > 4) {
notFound();
}
return (
<section className="mb-150 pt-[200px]">
<div className="container mx-auto">
<div className=" text-center">
<h1 className="from-0 to-primary/0 bg-gradient-to-b from-[white] to-100% bg-clip-text text-[140px] font-bold leading-[1] text-transparent">
Products {id}
</h1>
</div>
</div>
</section>
);
}

Within the page.jsx, import the notFound module from "next/navigation" and call the function based on any condition. Here, I have created a function that will call the notFound function wherever the post id length is greater than 4. As a result, /products/5 URL will throw a not-found error. 

However, at this moment the /products/[id] is using the root not-found.jsx to show the error messages. Now, it is time to change that and show a different error message for this subfolder only.

Let’s create a not-found.jsx file inside /products/[id] folder. And add the following codes:

"use client";
import Link from "next/link";
import {usePathname} from "next/navigation";

const ReviewNotFound = () => {
const pathname = usePathname();
return (
<section className="mb-150 pt-[200px]">
<div className="container mx-auto">
<div className=" text-center">
<h1 className="from-0 to-primary/0 bg-gradient-to-b from-[red] to-100% bg-clip-text text-[140px] font-bold leading-[1] text-transparent dark:text-transparent">
Something is Wrong
</h1>
<p className="text-2xl font-semibold -mt-16">{pathname}</p>
<h2 className="mb-9 text-[64px] font-bold leading-[1.22]">
Page in the Products List <br /> Are Not Available
</h2>
<Link
href="/"
className="bg-gray-800 py-5 px-6 rounded-xl"
>
Go Back-Home
</Link>
</div>
</div>
</section>
);
};
export default ReviewNotFound;

Now, whenever you run the code and go to the products whose ID is more than 4   like /products/10, you will see the following error message.

creating-a-custom-404-page-in-nextjs

Boom!! I have gone through almost all the possible scenarios of adding error messages using not-found.jsx in next.js. I hope you gathered some insightful information from this article. Feel free to get in touch with Staticmania if you have any queries or comments. Enjoy your coding!

Add E-Commerce on Yor Next.js Site
thumbnail

Adding eCommerce Functionality in Hugo with Snipcart

In today's digital age, establishing an online presence for your business is essential to reach a broader customer base and increase revenue

Read article
footer-particlefooter-particlefooter-particlefooter-particlefooter-particle
back-to-top