Error Handling & Not Found Pages
5 questions found
How do you create a custom error page for a specific route segment in the App Router?
Beginner
You add a file named error.js inside a route folder, which must be a client component, and Next.js automatically shows it whenever an error occurs while rendering that route or any of its nested pages, letting you display a friendly message instead of a broken page.
'use client';
export default function Error({ error, reset }) {
return (
<div>
<h2>Something went wrong.</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
Real-world example
A dashboard shows a friendly error message with a retry button whenever loading a user's data fails, instead of leaving them with a blank or broken screen.
Common follow-ups: Why does the error boundary file need to be a client component?;What does the reset function actually do when called?
Client Components & Hydration;Testing Next.js Applications
How do you create a custom 404 not found page in Next.js?
Beginner
You add a file named not-found.js to your app folder, and Next.js automatically shows it whenever a route does not match any page, or whenever you manually call the notFound function inside a page to indicate that specific content could not be found.
// app/not-found.js
export default function NotFound() {
return (
<div>
<h2>Page Not Found</h2>
<p>The page you are looking for does not exist.</p>
</div>
);
}
Real-world example
An online store shows a helpful custom 404 page with a search bar and popular product links whenever a customer visits a broken or outdated product link.
Common follow-ups: How do you trigger the not found page manually from inside a page component?;Can you have different not-found pages for different sections of your site?
Routing (App/Pages Router);Dynamic Routes & Catch-All Segments
How would you manually trigger a not found response when a specific piece of data, like a product, does not exist?
Intermediate
You call the notFound function imported from next/navigation inside your page or data fetching logic whenever the requested data cannot be found, which immediately stops rendering the current page and shows the closest not-found.js file instead, giving users an accurate 404 experience.
import { notFound } from 'next/navigation';
export default async function ProductPage({ params }) {
const { id } = await params;
const product = await getProduct(id);
if (!product) {
notFound();
}
return <h1>{product.name}</h1>;
}
Real-world example
A product page checks if the requested product id actually exists in the database, and shows the proper 404 page immediately if a customer tries to visit a product that has been removed.
Common follow-ups: What is the difference between calling notFound and just returning null?;Does calling notFound also set the correct HTTP status code?
Dynamic Routes & Catch-All Segments;Data Fetching
How does the global-error.js file differ from a regular error.js file in the App Router?
Intermediate
The global-error.js file, placed at the root of the app folder, catches errors that occur in the root layout itself, which regular error.js files cannot catch since they are nested inside the layout. It must include its own html and body tags since it replaces the entire root layout when an error happens there.
// app/global-error.js
'use client';
export default function GlobalError({ error, reset }) {
return (
<html>
<body>
<h2>A critical error occurred.</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
);
}
Real-world example
An application catches a rare error that occurs inside its root layout itself using global-error.js, preventing the entire site from showing a completely blank white screen to visitors.
Common follow-ups: Why does global-error.js need its own html and body tags?;How often does an error actually occur at the root layout level?
Layouts & Templates;Client Components & Hydration
How would you set up a comprehensive error handling strategy across a large Next.js application with many route segments?
Advanced
You place error.js files at strategic points in your route structure, such as near features that are more likely to fail, use a shared error reporting service to log errors to a monitoring tool, provide clear and actionable messages for users, and include a global-error.js as a final safety net for anything that escapes the nested boundaries.
'use client';
import { useEffect } from 'react';
import { logErrorToService } from '@/lib/monitoring';
export default function Error({ error, reset }) {
useEffect(() => {
logErrorToService(error);
}, [error]);
return <button onClick={() => reset()}>Try again</button>;
}
Real-world example
A large e-commerce platform places error boundaries around its checkout flow specifically, since that feature is business critical, while also logging every error to a monitoring service so the team is alerted quickly.
Common follow-ups: What monitoring tools are commonly used to track errors in production Next.js apps?;How do you avoid showing overly technical error details to end users?
Security Best Practices in Next.js;Testing Next.js Applications