Menu
Coddy logo textTech

Not Found Pages

Part of the Next.js Essentials section of Coddy's React journey — lesson 9 of 47.

A dynamic route is generous to a fault. app/menu/[slug]/page.jsx matches /menu/pizza, and it matches /menu/asdfgh just as happily, then renders a dish page for a dish that doesn't exist.

Next.js gives you both halves of the fix.

1. The 404 screen. A file named not-found.jsx, same special-filename club as page.jsx and layout.jsx:

// app/not-found.jsx
export default function NotFound() {
    return <h1>We don't have that</h1>;
}

Put it at app/not-found.jsx and it covers the whole app: every URL that matches nothing lands here, instead of on the plain built-in 404.

2. The trigger. Sometimes the URL matches a route but the data doesn't exist. That's the /menu/asdfgh case, and only your code can tell. Call notFound():

import { notFound } from 'next/navigation';

const dishes = ['pizza', 'pasta'];

export default async function Dish({ params }) {
    const { slug } = await params;

    if (!dishes.includes(slug)) {
        notFound();
    }

    return <h1>{slug}</h1>;
}

notFound() doesn't return a value and you don't return it: calling it stops the page right there and shows the nearest not-found.jsx. Everything after the if can safely assume the dish is real, which is why the guard goes at the top.

challenge icon

Challenge

Medium

/menu/sushi currently renders a dish page for a dish that isn't on the menu. Close the hole.

  1. Create app/not-found.jsx. Default-export a component that returns an <h1> with id="not-found-title" and the exact text Dish not found.
  2. In app/menu/[slug]/page.jsx, import notFound from next/navigation.
  3. If slug isn't in the dishes array, call notFound() before rendering anything.

/menu/pizza must still work.

Try it yourself

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Next.js Essentials