All Docs
FeaturesMaking Tax DigitalUpdated March 10, 2026

Branded Error Pages: Handling Runtime Failures Gracefully

Branded Error Pages: Handling Runtime Failures Gracefully

Release: v1.0.382 · Category: SEO / Technical

Overview

As of v1.0.382, the platform now includes proper Next.js error boundaries — error.tsx and global-error.tsx — ensuring that any unhandled runtime error presents a clear, branded recovery screen rather than the framework's bare default UI.

This matters most in a financial compliance context: users may encounter an error partway through a quarterly HMRC submission or while reviewing transaction data. Previously, they would have been stranded on a plain error screen with no way to recover or navigate away. Now they see a consistent page that tells them what went wrong and gives them an immediate path forward.

What Was Added

src/app/error.tsx — Subtree Error Boundary

This file is a Next.js error boundary for all routes rendered inside the root layout. It must be a client component:

'use client';

export default function Error({
  error,
  reset,
}: {
  error: Error;
  reset: () => void;
}) {
  return (
    <div className="flex min-h-screen flex-col items-center justify-center">
      <h1>Something went wrong</h1>
      <p>{error.message}</p>
      <button onClick={reset}>Try again</button>
      <Link href="/">Back to home</Link>
    </div>
  );
}

Key behaviours:

  • Receives the thrown error object and a reset function from Next.js.
  • Calling reset() re-renders the segment that failed, allowing the user to retry without a full page reload.
  • The "Back to home" link provides an unconditional escape route.

src/app/global-error.tsx — Root Layout Error Boundary

Errors thrown inside the root layout itself (e.g. in a shared provider or top-level component) are not caught by error.tsx. global-error.tsx handles this case. Because it replaces the root layout when active, it must include its own <html> and <body> tags and any critical shell markup.

Key behaviours:

  • Activates only when the root layout throws.
  • Mirrors the same props interface as error.tsx (error + reset).
  • Ensures no error state — however catastrophic — results in an unbranded screen.

Error Handling Hierarchy

Runtime error thrown
        │
        ▼
Is the root layout responsible?
   ├── Yes → global-error.tsx
   └── No  → error.tsx (nearest boundary up the tree)

Impact on Users

ScenarioExperience
API call fails during HMRC submissionBranded error page; user can retry or go home
Unexpected exception in a route segmentBranded error page; rest of the app unaffected
Root layout crashes (e.g. broken provider)global-error.tsx catches it; user is not stranded

Related Work

This fix is part of a broader SEO and technical health initiative (SEO-25) that also identified the absence of not-found.tsx for 404 states. Taken together, these changes ensure all error states — 404s, runtime errors, and root-level failures — produce consistent, navigable UI rather than bare framework defaults.