not-found.tsx

Show a custom 404 UI with not-found.tsx, and trigger it programmatically with notFound().

Syntaximport { 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.tsx renders with a 404 status.
  • You call notFound() in a Server Component to bail out.

Example

Example Β· typescript
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.

Example Β· ts
// 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.

Example Β· ts
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.

Example Β· bash
app/
β”œβ”€β”€ not-found.tsx          # global 404
└── blog/
    └── [slug]/
        β”œβ”€β”€ page.tsx
        └── not-found.tsx  # blog-specific 404

Discussion

  • Be the first to comment on this lesson.
not-found.tsx β€” Next.js | SoundsCode