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
Medium/menu/sushi currently renders a dish page for a dish that isn't on the menu. Close the hole.
- Create
app/not-found.jsx. Default-export a component that returns an<h1>withid="not-found-title"and the exact textDish not found. - In
app/menu/[slug]/page.jsx, importnotFoundfromnext/navigation. - If
slugisn't in thedishesarray, callnotFound()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>
);
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Next.js Essentials
2Routing & Links
Folders Are RoutesNested RoutesLinking PagesDynamic RoutesNot Found PagesRecap: Routing