# Next.js error boundary to fix client-side exceptions

> Error Boundaries allow the other parts of your application to keep working when there is an error in an isolated component or piece of code.

**URL:** https://sentry.io/answers/next-js-client-side-exception/

---

## The Problem

Occasionally, when building a Next.js application, you might encounter a hard-to-debug error that causes your component (or page) not to render. These client-side exceptions are often caused by a bug in your code, or a third-party API that you depend on.

## The Solution

### Debugging

The best way to identify and fix client-side errors in React and Next.js is through the use of [Error Boundaries](https://nextjs.org/docs/pages/building-your-application/configuring/error-handling#handling-client-errors).

In React, if your application throws an error during rendering, React will remove its UI from the screen.

Error Boundaries allow the other parts of your application to keep working when there is an error in an isolated component or piece of code. It also allows you to provide a fallback component and log error information.

In Next.js, Error Boundaries are used by creating an `ErrorBoundary` component:

```jsx
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props)
    this.state = { hasError: false }
  }

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

  componentDidCatch(error, errorInfo) {
    console.log({ error, errorInfo })
  }
  render() {
    if (this.state.hasError) {
      return (
        <div>
          <h2>Oops, there is an error!</h2>
          <button
            type="button"
            onClick={() => this.setState({ hasError: false })}
          >
            Try again?
          </button>
        </div>
      )
    }
    return this.props.children
  }
}

export default ErrorBoundary
```

This `ErrorBoundary` component is then used to wrap the `Component` property in `pages/_app.js` if you're using the Pages router.

```jsx
import ErrorBoundary from '../components/ErrorBoundary'

function MyApp({ Component, pageProps }) {
  return (
    <ErrorBoundary>
      <Component {...pageProps} />
    </ErrorBoundary>
  )
}

export default MyApp
```

Currently, there isn't a way to write an Error Boundary as a class-free function component for the Pages router in Next.js. If you don't want to write and maintain the `ErrorBoundary` component yourself, you can use a [package](https://github.com/bvaughn/react-error-boundary) that implements a reusable component. In the App Router, Next.js 16.3+ provides [`catchError()`](https://nextjs.org/docs/app/api-reference/functions/catchError) as a built-in way to create error boundaries in function components.

If you are using the App router, you can use the `error.js` file convention instead. This useful feature of Next.js wraps a route segment and its children in an Error Boundary.

You can use the `error.js` convention by creating the file inside a route segment and exporting a React component. Error components must be client components.

```tsx
'use client'

import { useEffect } from 'react'

export default function Error({
  error,
  reset,
}: {
  error: Error & { digest?: string }
  reset: () => void
}) {
  useEffect(() => {
    console.error(error)
  }, [error])

  return (
    <div>
      <h2>Something went wrong!</h2>
      <button
        onClick={
          () => reset()
        }
      >
        Try again
      </button>
    </div>
  )
}
```

When a runtime exception is thrown from anywhere in the route segment, the `error.js` component is triggered. You can add your own error logging and reporting logic to the `useEffect` function. When the `Try again` button is clicked in this scenario, the function will try to re-render the contents of the Error Boundary.

In Next.js 16.3+, the `error.js` convention also provides a `retry()` prop that calls `router.refresh()` and `reset()` within a transition, re-fetching data from the server before re-rendering. This is preferred over `reset()` alone when the error originates from data fetching.

### Common Causes

Below are a few common causes to look out for when debugging this error.

#### Invalid `props`

Client-side exceptions can occur when invalid props are passed down from parent to child components. If you're using TypeScript, it is recommended to strong-type your props so that you can be certain that your components are receiving what they need.

In the following example, we allow our `props` to be of type `any`, which can result in exceptions when the component is rendered:

```tsx
interface Props {
  slug: any;
  content: any;
}

export const Post: React.FC<Props>  = ({slug, content}) => {
 // We might assume that `slug` is a URL here
}

export default function Dashboard() {
  return (
   <div>
    <Post slug={5} content={"My Content"} />
   </div>
  )
}
```

To ensure that the Dashboard component uses the Post component correctly, we can strongly type our `props` as follows:

```ts
interface Props {
  slug: string;
  content: string;
}
```

#### Check API Responses and Uptime

If your application depends on a backend server, there might be an issue with the API response. Ensure that your code can deal with error responses from APIs, as well as failed network requests when APIs aren't available.

#### Missing Environment Variables

If you are deploying your Next.js application to Vercel (or another hosting provider), check whether you have properly configured the environment variables for your production environment. Compare the contents of your `.env` file locally to the environment variables in the dashboard or configuration of your hosting provider.

## Debugging Client-Side Errors in Production

While Error Boundaries help you catch and handle exceptions gracefully, understanding why client-side errors happen in production requires deeper visibility. [Session replay](https://sentry.io/product/session-replay/) captures the user's interaction leading up to an error, showing you exactly what they clicked, what data was present, and how the UI behaved before the exception occurred. Combined with [application monitoring](https://sentry.io/), you can see patterns across multiple users—whether errors are browser-specific, triggered by certain user flows, or caused by specific API responses. Production errors often surface issues you'll never reproduce locally, making these tools essential for debugging real-world client-side exceptions.

## Further Reading

- [Next.js Pages Router Error Handling](https://nextjs.org/docs/pages/building-your-application/configuring/error-handling#handling-client-errors)
- [Next.js App Router Error Handling](https://nextjs.org/docs/app/getting-started/error-handling)

---

*Source: [sentry.io/answers/next-js-client-side-exception/](https://sentry.io/answers/next-js-client-side-exception/)*
