Blog
3 min read

React Error Boundaries: Stop One Broken Component Crashing the Page

Without an error boundary, one component throwing during render blanks your entire React app. How error boundaries work, using react-error-boundary with fallbacks and reset, Next.js error.tsx and global-error.tsx, what boundaries don't catch, and reporting errors to monitoring.

By default, if any React component throws an error while rendering, React unmounts the whole tree — the user gets a blank white page. One bad API response in a sidebar widget takes down the entire app. (React app shows a blank page)

An error boundary catches errors in the components below it and shows a fallback instead, so the rest of the page keeps working.

Using react-error-boundary

Writing boundaries by hand requires a class component. The react-error-boundary package is the standard way:

npm install react-error-boundary
import { ErrorBoundary } from 'react-error-boundary'

function Fallback({ error, resetErrorBoundary }) {
  return (
    <div role="alert">
      <p>This section couldn't load.</p>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  )
}

export function Dashboard() {
  return (
    <>
      <Header />
      <ErrorBoundary FallbackComponent={Fallback} onError={(error, info) => reportError(error, info)}>
        <RevenueChart />
      </ErrorBoundary>
      <ErrorBoundary FallbackComponent={Fallback}>
        <RecentOrders />
      </ErrorBoundary>
    </>
  )
}

If RevenueChart throws, only that box shows the fallback. The header and orders keep working.

  • resetErrorBoundary re-renders the children — useful after a transient failure.
  • resetKeys={[userId]} resets automatically when a value changes.
  • onError is where you send the error to monitoring.

Where to put boundaries

  • One at the top of the app — a friendly "something went wrong" page instead of white.
  • Around independent sections — widgets, panels, charts, third-party embeds.
  • Around each route, so navigating away recovers.

Not around every tiny component — that hides bugs and clutters code.

Next.js App Router: error.tsx

Next.js builds boundaries in. An error.tsx file in a route folder wraps that route segment:

// app/dashboard/error.tsx
'use client'

export default function Error({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
  return (
    <div>
      <h2>Something went wrong loading the dashboard.</h2>
      <button onClick={() => reset()}>Try again</button>
    </div>
  )
}
  • It must be a client component.
  • Errors from server components arrive with the message hidden in production (only a digest you can match in server logs) — so you don't leak details to users.
  • global-error.tsx in app/ catches errors in the root layout itself.
  • not-found.tsx handles 404s separately.

What error boundaries don't catch

They only catch errors during rendering, in lifecycle methods, and in constructors of components below them. They do not catch:

  • errors in event handlers (onClick) — use try/catch there,
  • errors in async code (fetch().then, setTimeout) — handle them and set error state,
  • errors in the boundary itself,
  • server-side errors outside React rendering.

To push an async error into the nearest boundary, react-error-boundary provides useErrorBoundary:

const { showBoundary } = useErrorBoundary()
fetchData().catch(showBoundary)

Data libraries like TanStack Query can also throw errors into boundaries via an option. (TanStack Query vs useEffect)

Report what you catch

A caught error is still a bug. Send it to error monitoring (Sentry or similar) with the component stack, so you know it happened. (Error monitoring for beginners)

Write the fallback for humans

  • Say what didn't work, in plain words.
  • Offer a way forward: retry, go home, contact support.
  • Don't show stack traces to users.

Fix the cause too

Boundaries contain damage; they don't fix it. The usual culprits are unhandled undefined data and unexpected API shapes. (Cannot read properties of undefined, Objects are not valid as a React child)


EasySpawn runs your app with logs and errors in one place on your server, so when a boundary catches something, Claude Code can find the cause and fix it. See how it works or join the waitlist.

Related: React App Shows a Blank Page After Deploying · Error Monitoring for Beginners · Next.js Hydration Errors · Debugging for Beginners

Keep reading