Error States
One morning Trailhead's trail database is unreachable. Without any error handling, visitors to a trail page get a bare error screen and lose the header and navigation too. With error files, only the broken part shows a friendly message and a retry button, while the rest of the site keeps working.
The rule
errorcatches what breaks below it;not-foundcovers what is missing.
error.tsx puts a React error boundary around its segment's page and everything below it. When rendering throws, the boundary shows your fallback instead. It must be a client component, because error boundaries run in the browser:
// app/trails/[slug]/error.tsx
"use client";
export default function TrailError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div role="alert">
<p>We couldn't load this trail right now.</p>
<button onClick={() => reset()}>Try again</button>
</div>
);
}resettries to render the segment again, useful for brief outages.- In production, errors thrown in server components reach the browser without their original message, to avoid leaking details;
digestis an ID you can match in server logs.
The boundary sits inside the layout of the same folder, so the header and the trails sidebar stay on screen. One consequence: an error.tsx cannot catch errors thrown by the layout.tsx beside it. Those go to the error file one level up. For errors in the root layout there is app/global-error.tsx, which replaces the whole document and so must render its own <html> and <body>.
Missing content is not a crash. When a slug matches no trail, call notFound() from next/navigation. It renders the nearest not-found.tsx and responds with a 404 status:
// app/trails/[slug]/not-found.tsx
import Link from "next/link";
export default function TrailNotFound() {
return <p>No such trail. <Link href="/trails">See all trails</Link></p>;
}The shortcut
Classify the failure: "Did something break, or is something missing?" Broken (a throw, an outage): error.tsx, with "use client" and a retry. Missing (unknown slug): notFound() and not-found.tsx. Then place the file as deep as possible, so the smallest area is replaced.
Unknown slug
Missing. The page calls
notFound();not-found.tsxshows a helpful 404.
The trap is forgetting "use client" in error.tsx. The file takes an onClick and runs in the browser, so without the directive the build fails.
Drills
Answer fast — trust the rule.
What must the first line of an error.tsx file be?
What does calling reset() in an error fallback do?
A trail slug matches nothing in the database. What should the page do?
app/trails/layout.tsx throws. Which file can catch it?
Remember
error.tsxcatches what breaks below it;notFound()andnot-found.tsxcover what is missing.- Shortcut: broken or missing? Then place the file as deep as possible.
- Trap:
error.tsxmust be a client component, and it cannot catch its own folder's layout.
