CPCODELAB
Next.js

Special Files: loading, error, and not-found

9 min read

The Full Set of Special Files

Beyond page.tsx and layout.tsx, Next.js reserves several filenames that each handle a different lifecycle state of a route segment.

  • loading.tsx — Rendered as a <Suspense> fallback while the page is fetching data.
  • error.tsx — Renders when an unhandled error is thrown in the segment (must be "use client").
  • not-found.tsx — Renders when notFound() is called from anywhere in the segment.
  • template.tsx — Like layout.tsx but re-mounts on every navigation (loses state).
  • default.tsx — Fallback for parallel routes when no matching slot is active.

Triggering not-found

tsx
// src/app/blog/[slug]/page.tsx
import { notFound } from "next/navigation";

export default async function PostPage({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await fetchPost(slug);

  if (!post) {
    notFound(); // renders not-found.tsx in this segment
  }

  return <article><h1>{post.title}</h1></article>;
}

async function fetchPost(slug: string) {
  const res = await fetch(`https://api.example.com/posts/${slug}`);
  if (!res.ok) return null;
  return res.json();
}
tsx
// src/app/blog/[slug]/not-found.tsx
export default function NotFound() {
  return (
    <div>
      <h2>Post Not Found</h2>
      <p>The post you are looking for does not exist.</p>
    </div>
  );
}

error.tsx only catches errors thrown during rendering. Errors in event handlers or async logic outside of render must be handled manually with try/catch.

Ready to test yourself?
Practice Next.js— quiz & coding exercises