React Error Boundary Production

How to Create a React Error Boundary Component in 2026

How to create a React Error Boundary Component

Why you need Error Boundaries in production

When a React component throws during rendering, the entire component tree unmounts — your users see a blank screen with no explanation. An Error Boundary is a wrapper component that catches rendering errors from its children and shows a fallback UI instead of crashing the whole app.

Before 2023, Error Boundaries required class components with componentDidCatch and getDerivedStateFromError. In 2026, the idiomatic approach is the react-error-boundary package, which provides a fully-featured boundary as a functional component.

The old way — class component (avoid in 2026)

❌ Outdated — class-based Error Boundary

// ❌ Works, but verbose and requires a class component.
// Not compatible with hooks. Avoid for new code.

import React from 'react';

class OldErrorBoundary extends React.Component<
  { children: React.ReactNode },
  { hasError: boolean }
> {
  constructor(props: any) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() {
    return { hasError: true };
  }

  componentDidCatch(error: Error, info: React.ErrorInfo) {
    console.error(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) return <h2>Something went wrong.</h2>;
    return this.props.children;
  }
}

The modern way — react-error-boundary

✅ Install the package

npm install react-error-boundary
# or
pnpm add react-error-boundary

Basic usage — drop-in wrapper

✅ Wrap any component tree prone to errors

// app/layout.tsx (Next.js App Router example)
"use client"; // Error Boundary must be a Client Component

import { ErrorBoundary } from 'react-error-boundary';

function FallbackUI({ error, resetErrorBoundary }: {
  error: Error;
  resetErrorBoundary: () => void;
}) {
  return (
    <div role="alert" style={{ padding: '2rem', textAlign: 'center' }}>
      <h2>Something went wrong</h2>
      <pre style={{ color: 'red', fontSize: '0.85rem' }}>{error.message}</pre>
      <button onClick={resetErrorBoundary}>Try again</button>
    </div>
  );
}

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <ErrorBoundary FallbackComponent={FallbackUI}>
          {children}
        </ErrorBoundary>
      </body>
    </html>
  );
}

Auto-reset on route change (Next.js App Router)

After an error, the boundary stays in its error state even if the user navigates away. Use resetKeys to reset the boundary whenever the route changes.

✅ Auto-reset when pathname changes

"use client";

import { usePathname } from 'next/navigation';
import { ErrorBoundary } from 'react-error-boundary';

export function NavigationAwareErrorBoundary({
  children
}: {
  children: React.ReactNode
}) {
  const pathname = usePathname();

  return (
    <ErrorBoundary
      FallbackComponent={FallbackUI}
      resetKeys={[pathname]}  // boundary resets every time pathname changes
    >
      {children}
    </ErrorBoundary>
  );
}

Log errors to your monitoring service

Use the onError prop to send errors to Sentry, Datadog, or any observability platform.

✅ Connect to Sentry (or any logging service)

import * as Sentry from '@sentry/nextjs';
import { ErrorBoundary } from 'react-error-boundary';

function logBoundaryError(error: Error, info: { componentStack: string }) {
  Sentry.withScope(scope => {
    scope.setTag('source', 'error-boundary');
    scope.setExtra('componentStack', info.componentStack);
    Sentry.captureException(error);
  });
}

export function MonitoredErrorBoundary({ children }: { children: React.ReactNode }) {
  return (
    <ErrorBoundary
      FallbackComponent={FallbackUI}
      onError={logBoundaryError}
    >
      {children}
    </ErrorBoundary>
  );
}

Trigger the boundary programmatically from async code

Error Boundaries only catch rendering errors. They do not catch errors inside event handlers or async useEffect calls. Use the useErrorBoundary hook to manually forward async errors to the nearest boundary.

✅ Forward async errors to the Error Boundary

import { useErrorBoundary } from 'react-error-boundary';

export function DataLoader() {
  const { showBoundary } = useErrorBoundary();

  useEffect(() => {
    fetch('/api/data')
      .then(r => {
        if (!r.ok) throw new Error(`HTTP ${r.status}`);
        return r.json();
      })
      .then(setData)
      .catch(showBoundary); // forwards error to nearest ErrorBoundary
  }, [showBoundary]);

  return <div>{data}</div>;
}

Frequently Asked Questions

Should I have one global Error Boundary or many nested ones?

Both. Use a global boundary at your app root as a last-resort catch-all. Then add local boundaries around isolated features (widgets, sidebars, data-heavy panels) so a crash in one section doesn't unmount the entire page. This gives users a degraded-but-functional experience instead of a blank screen.

Does Error Boundary work in React Server Components (Next.js App Router)?

Error Boundaries must be Client Components ("use client" at the top). Server Components use Next.js's built-in error.tsx file convention as their boundary equivalent. Place an error.tsx file in the same directory as a page.tsx to catch server-side render errors for that route segment.

What errors does Error Boundary NOT catch?

Error Boundaries do not catch: (1) errors in event handlers — use try/catch there, (2) errors in asynchronous code like setTimeout or fetch — use useErrorBoundary().showBoundary() as shown above, (3) errors during server-side rendering — use Next.js error.tsx, (4) errors thrown in the Error Boundary itself.