Skip to content
Watch the complete Next.js 15 course on YouTube

Not found page

This page explains how to implement custom 404 pages in Next.js using the not-found.tsx file.

Default behavior

By default, Next.js displays a basic 404 page for non-existent routes which is suitable for development. You can customize this page for production use.

Creating a custom 404 page

Create a not-found.tsx file in your app directory:

app/not-found.tsx
export default function NotFound() {
return (
<div>
<h2>Page Not Found</h2>
<p>Could not find requested resource</p>
</div>
);
}

When you navigate to a non-existent route, /route-that-does-not-exist, the above 404 page will be displayed.

Programmatic usage

You can trigger the 404 page programmatically using the notFound function from next/navigation.

Assuming a product can have a maximum of 1000 reviews, you can trigger the 404 page for reviews above 1000:

app/reviews/[reviewId]/page.tsx
import { notFound } from "next/navigation";
export default async function ReviewPage({
params,
}: {
params: Promise<{ reviewId: string }>;
}) {
const { reviewId } = await params;
// Example: Show 404 for review IDs above 1000
if (parseInt(reviewId) > 1000) {
notFound();
}
return (
<div>
<h1>Review #{reviewId}</h1>
<p>This is the review content...</p>
</div>
);
}

Route-specific 404 pages

You can create route-specific 404 pages by adding not-found.tsx files in route directories. Next.js uses the most specific matching 404 page in the route hierarchy.

Example for a review-specific 404 page:

app/reviews/[reviewId]/not-found.tsx
export default function NotFound() {
return (
<div>
<h2>Review not found</h2>
</div>
);
}

Dynamic content in 404 pages

Often, it is beneficial to use the route parameters in your 404 page to render meaningful messages. However, the component defined in not-found.tsx does not have access to route parameters as props. To include route parameters in your 404 page, you need to convert the component to a client component and use the usePathname hook:

  1. Add the use client directive at the top of your file:

  2. Use the usePathname hook to get the route parameters:

app/reviews/[reviewId]/not-found.tsx
import { usePathname } from "next/navigation";
export default function NotFound() {
const pathname = usePathname();
const reviewId = pathname.split("/")[2]; // pathname is /reviews/1001/
return <h2>Review {reviewId} not found</h2>;
}

When you navigate to /reviews/1001, the 404 page will display “Review 1001 not found”.