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 whennotFound()is called from anywhere in the segment.template.tsx— Likelayout.tsxbut 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