ReactHustle

How to Create Custom 404 Page in NextJS 12

Jasser Mark Arioste

Jasser Mark Arioste

How to Create Custom 404 Page in NextJS 12

Hello, hustler! In this tutorial, you'll learn two different ways to create custom 404 pages in NextJS 12 using the pages directory. We'll also use TailwindCSS for the fast and easy utility classes styling and Typescript.

Why Create a Custom 404 Page? #

One of the main principles in developing websites is to keep the users for as long as possible and prevent them from leaving. When they encounter a 404 page, they'll usually leave the website if there's nothing to keep them there.

Why Does Page Not Found Errors Occur? #

There are many reasons for this but I think the most common reasons are the following:

  1. The page has been deleted from your website.
  2. The page slug has been updated but a 301 or 302 redirect was not set up. For example, your post has the URL of /posts/next-js-guide-2022, and was updated to /posts/next-js-guide-2023. If there's another website that links to /posts/next-js-guide-2022 and a redirect is not present, this results in a 404 error. This is a very common scenario.

How to Prevent Visitors From Leaving? #

There are several ways to prevent visitors from leaving the website once they land on a 404 page. One piece of information we have is the URL so here are some possible options:

  1. Add some links to similar pages based on the URL or slug.
  2. Add some links to your home page so that the user has the chance to explore your website.
  3. Add a search bar so that the user can at least search for a page.

All right so in this tutorial, we'll implement a custom 404 page that has the first two methods mentioned.

Final Output #

Here's the final output of what we'll be making today:

Step 1 - Project Setup #

Let's create a new NextJS project with TailwindCSS preinstalled. I created a starter template in GitHub to easily achieve this. Run the command:

npx create-next-app -e https://github.com/jmarioste/next-tailwind-starter-2 next-custom-404-page

Once it has completed installing, you can run the following command to start the local dev server:

cd next-custom-404-paeg
yarn dev

Step 2 - Overriding the Default 404 Page #

To override the default 404 page in the /pages directory, it's actually pretty simple. We just have to create the pages/404.tsx or pages/404.jsx if you're using javascript :

// pages/404.tsx
import Link from "next/link";
const Custom404 = () => {
  return (
    <div className="grid place-content-center h-screen">
      <div className="container mx-auto max-w-md text-center">
        <h1 className="text-4xl font-bold text-zinc-700 my-4">
          404 - Page Not Found
        </h1>
        <p className="text-zinc-400">
          Sorry, we could not find the page you are looking for. Instead, here
          are some similar pages that could help:
        </p>
        {/*TODO: List similar pages here */}
        {/*TODO: Create Search bar component here */}
        <div className="border border-b-gray-50 my-4"></div>
        {/* Add navigation to important pages */}
        <div>
          <Link
            className="hover:underline hover:text-indigo-400 text-indigo-500"
            href="/"
          >
            Go to Home Page
          </Link>
        </div>
      </div>
    </div>
  );
};
export default Custom404;
123456789101112131415161718192021222324252627282930

Here, we're just creating a page that has a link to our homepage. Later, we'll add the <SearchSuggestions/> and <SearchBar/> components

After this step, once we go to a non-existing URL like http://localhost:3000/product/iphone, it shows our custom 404 page:

Custom 404 Page in NextJS

Step 3 - Adding Search Suggestions #

This step is optional depending on your requirements but I think this will help the users a lot. Let's assume that we have an e-commerce web app, and we want to suggest a product based on the URL. So for this, we're going to use Dummyjson API as our backend API since they can give us some product suggestions.

First, let's create the file components/SearchSuggestions.tsx:

// components/SearchSuggestions.tsx
const SearchSuggestions = () => {
  return <div>SearchSuggestions</div>;
};
export default SearchSuggestions;
12345

Next, we'll add the logic to call DummyJSON API. Let's install the useFetch custom hook from usehooks-ts to act as our HTTP client as this will make our lives a lot easier. If you're using react-query or swr, that's even better.

yarn add usehooks-ts
1

Now, let's add the logic. Explanations are in the comments:

import Link from "next/link";
import { useRouter } from "next/router";
import { useFetch } from "usehooks-ts";

// Step 0 : Define the types
// API Response
type SearchResponse = {
  products: {
    title: string;
  }[];
};

type SearchSuggestion = {
  title: string;
  url: string;
};

const SearchSuggestions = () => {
  const router = useRouter();
  // Step 1: Parse the router path

  const query =
    router.asPath
      .split("/")
      .filter((q) => !!q)
      .pop() ?? ""; // transforms: "/products/iphone" into "iphone"

  // Step 2: Create the URL
  // We're using dummyjson as an example
  // Most likely you have your own search api or If you're using algolia, that's even better.
  const url = new URL("https://dummyjson.com/products/search");
  url.searchParams.set("q", query);
  url.searchParams.set("limit", "4");

  // Step 3: Call the search API using useFetch. This can be improved If you have your search API
  const { data = { products: [] }, error } = useFetch<SearchResponse>(
    url.toString()
  );

  // Step 4: Map the results to our list of suggestions to show the user
  const suggestions = data?.products.map<SearchSuggestion>((p) => {
    return {
      title: p.title,
      // using home page route since the api doesn't return some kind of URL.
      url: "/",
    };
  });

  if (!data || error) return null;

  // Step 5: render the alternative suggestions
  return (
    <ul className="grid grid-cols-2 my-2">
      {suggestions.map((item, index) => (
        <li key={index}>
          <Link
            href={item.url}
            className="hover:underline hover:text-indigo-400 text-indigo-500 "
          >
            {item.title}
          </Link>
        </li>
      ))}
    </ul>
  );
};

export default SearchSuggestions;


1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768

After this step, you'll get this result when navigating to /product/iphone:

NextJS Custom 404 Page with page suggestions

We got two suggestions based on the route, not bad.

Full Code and Demo #

The full code is available on Github: jmarioste/nextjs-custom-404-page-tutorial

The demo is available on Stackblitz: nextjs-custom-404-page-tutorial. Be sure to navigate to /products/iphone to show the 404 error page.

Conclusion #

We learned how to create custom 404 pages in NextJS. which gives us more probability for the user to stay on the site longer.

If you like this tutorial, please leave a like or share this article. For future tutorials like this, please subscribe to our newsletter or follow me on Twitter.

References #

Credits: Image by Анатолий Стафичук from Pixabay

Share this post!

Related Posts

Disclaimer

This content may contain links to products, software and services. Please assume all such links are affiliate links which may result in my earning commissions and fees.
As an Amazon Associate, I earn from qualifying purchases. This means that whenever you buy a product on Amazon from a link on our site, we receive a small percentage of its price at no extra cost to you. This helps us continue to provide valuable content and reviews to you. Thank you for your support!
Donate to ReactHustle