The framework default 404 page is a dead end: it names the HTTP status, nothing else, and offers no path back into the product. Users who mistype a URL, follow a stale email link, or hit a deleted resource bounce to the browser back button and often leave entirely. A custom 404 recovers that intent by handing users a home link, a search, or suggested pages, which directly affects bounce rate, session depth, and organic-traffic retention from broken inbound links.
Medium because every site serves 404s in production, but the failure only affects users who already took a wrong turn.
Create app/not-found.tsx (App Router) or pages/404.tsx (Pages Router) with a plain-language heading, a one-sentence explanation, and at least one navigation control — a home link, a search input, or a list of popular destinations. Match the site's layout and typography so users recognize they are still inside the product.
// app/not-found.tsx
import Link from 'next/link'
export default function NotFound() {
return (
<div className="flex flex-col items-center gap-4 p-8">
<h1>Page not found</h1>
<Link href="/">Go to homepage</Link>
</div>
)
}
ID: saas-error-handling.user-errors.not-found-custom-helpful
Severity: medium
What to look for: For Next.js App Router: check for app/not-found.tsx. For Next.js Pages Router: check for pages/404.tsx. For other frameworks: check for the equivalent custom 404 page file. Evaluate the content: (1) Does it clearly communicate that the page wasn't found (in plain language, not HTTP jargon)? (2) Does it provide navigation options — a link to the home page, a search field, or a list of popular pages? (3) Does it match the site's design (not a bare-bones default)? Check that a custom 404 file actually exists — framework defaults are acceptable fallbacks but are a fail for this check.
Pass criteria: Count all navigation options on the custom 404 page (home link, search, suggested pages). Pass if a custom 404 file exists AND it contains both an explanation of the error and at least 1 navigation option (home link, search, or suggested pages). Extract and quote the heading and first navigation element from the 404 page to verify it is helpful. Report even on pass: "Custom 404 provides X navigation options."
Fail criteria: Fail if no custom 404 file exists (relying on framework default). Fail if the custom 404 exists but contains only a message with no navigation options. Do NOT pass when the 404 page uses only technical jargon ("404 Not Found") as its primary heading without a plain-language explanation.
Skip (N/A) when: Never — all web applications serve routes and can encounter 404 conditions.
Detail on fail: "No app/not-found.tsx found; using Next.js default 404" or "pages/404.tsx exists but contains only 'Page not found' with no navigation links". Max 500 chars.
Remediation: Default 404 pages strand users with no path forward. A helpful 404 keeps users in your application instead of bouncing them to the browser's back button.
For Next.js App Router:
// app/not-found.tsx
import Link from 'next/link'
export default function NotFound() {
return (
<div className="flex flex-col items-center justify-center min-h-screen gap-4">
<h1 className="text-4xl font-bold">Page not found</h1>
<p className="text-muted-foreground">
We couldn't find what you were looking for.
</p>
<Link href="/" className="btn-primary">Go to homepage</Link>
</div>
)
}
Consider adding a search input or links to your most important pages (dashboard, docs, support) so users can self-navigate to where they intended to go.