not-found.tsx
Show a custom 404 UI with not-found.tsx, and trigger it programmatically with notFound().
Syntax
import { notFound } from 'next/navigation';The not-found.tsx file renders when content is missing. It shows automatically for unmatched URLs, and you can trigger it yourself by calling the notFound() function β for example when a database lookup returns nothing.
Two ways it appears
- A URL matches no route β the nearest
not-found.tsxrenders with a 404 status. - You call
notFound()in a Server Component to bail out.
Example
import { notFound } from 'next/navigation';
export default async function Product({
params,
}: {
params: Promise<{ id: string }>;
}) {
const { id } = await params;
const product = await getProduct(id);
if (!product) notFound(); // renders not-found.tsx, sends 404
return <h1>{product.name}</h1>;
}When to use it
- A blog post page calls notFound() when the requested slug does not exist in the database.
- An admin panel shows a branded 404 page via not-found.tsx instead of the default Next.js not-found screen.
- A dynamic product page triggers notFound() when the product ID is valid syntax but returns no record from the API.
More examples
Custom not-found.tsx
not-found.tsx at the app root replaces Next.js default 404 with a branded, navigable page.
// app/not-found.tsx
import Link from 'next/link';
export default function NotFound() {
return (
<div>
<h1>404 β Page Not Found</h1>
<p>The page you are looking for does not exist.</p>
<Link href="/">Back to home</Link>
</div>
);
}Trigger notFound() in a page
Calling notFound() throws a special signal that Next.js catches to render the nearest not-found.tsx.
import { notFound } from 'next/navigation';
import { getPost } from '@/lib/posts';
export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
const post = await getPost(slug);
if (!post) notFound();
return <article>{post.title}</article>;
}Scoped not-found per segment
Placing not-found.tsx inside a segment overrides the global one for missing routes in that subtree.
app/
βββ not-found.tsx # global 404
βββ blog/
βββ [slug]/
βββ page.tsx
βββ not-found.tsx # blog-specific 404
Discussion