Next.js cookbook · Beginner
Handle errors and 404s in the App Router
Show friendly error pages per section, recover with a retry, and return real 404s for missing records.
Approach
Add error.tsx (a Client Component boundary) in route segments to catch rendering errors with a reset() retry, global-error.tsx for root-layout failures, and call notFound() when data doesn't exist so not-found.tsx renders with a 404 status. Log errors to your monitoring tool.
Solution
// app/projects/[id]/page.tsx
import { notFound } from "next/navigation";
export default async function ProjectPage({ params }: { params: Promise<{ id: string }> }) {
const project = await getProject((await params).id);
if (!project) notFound();
return <ProjectView project={project} />;
}
// app/projects/[id]/not-found.tsx
export default function NotFound() {
return <div><h2>Project not found</h2><a href="/projects">Back to projects</a></div>;
}
// app/projects/error.tsx
"use client";
import { useEffect } from "react";
export default function ProjectsError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
useEffect(() => { reportError(error); }, [error]);
return (
<div role="alert">
<h2>Something went wrong loading projects.</h2>
<p>Reference: {error.digest}</p>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
Pitfalls
error.tsxwithout"use client".- Rendering an empty page instead of
notFound()(soft 404s hurt SEO). - Exposing server error messages — production errors are sanitized; use the
digestto correlate logs.
Variations
instrumentation.tsonRequestErrorhook to report server errors centrally.
Further reading: Next.js: Error handling
Reference: https://nextjs.org/docs/app/getting-started/error-handling
More Next.js recipes
- Add a Content Security Policy with nonces in Next.js
- Add dark mode to Next.js without a flash
- Add SEO metadata, Open Graph and sitemaps
- Avoid data-fetching waterfalls in Server Components
- Build a validated JSON API with Route Handlers
- Create encrypted session cookies in Next.js
- Handle forms with Server Actions and validation
- Keep secrets and server code out of the client bundle