# How to use custom error pages

Source: https://dev.arcxp.com/pagebuilder-engine/how-to-guides/optimization-and-deployment/how-to-use-custom-error-pages/

How to use custom error pages for 404, 410, 500, and other HTTP status codes in PageBuilder Engine

## Implementation

If during rendering an error occurs, PageBuilder Engine will by default print out the error. While this behavior is useful during site buildout, in production we want to make these errors more user friendly. To facilitate this, PageBuilder Engine automatically looks for pages at the path `/error/{statusCode}` and if found will serve these in place of the default error message.

## Example: 404 Not Found page

We want to have a 404 page that displays a “Sorry Not Found” message. To do this we would create and publish a page from the PageBuilder Editor called `/error/404` and add to it our standard features (header, footer, etc) as well as a feature that displays our not found message. Now, when a user comes to a URL that results in a 404 they will see our custom 404 page instead of a default error message.

## Example: 410 Gone page

The `410 Gone` status code indicates that content previously existed at a URL but has been permanently removed. Unlike a `404`, a `410` signals to search engines that the content is intentionally gone and should be de-indexed.

To return `410` responses, you need two things: a content source that throws the `410` status code, and a custom error page to display to visitors.

### Create a content source that returns 410

In your content source’s `fetch` function, throw an error with `statusCode` set to `410` when the requested path matches content you have removed.

> **Tip:**
> 
> Use `fetch` instead of `resolve` when you need to conditionally throw errors. A `resolve` function processes default errors automatically, which prevents custom error logic from running. See [](https://dev.arcxp.com/pagebuilder-engine/how-to-guides/components-and-content/error-handling-in-content-sources) for details.

```js
const defined410Paths = [
  /^\/old-section(\/.*)?$/,
  /^\/archived-content(\/.*)?$/,
  // add patterns for removed sections, categories, or stories
];

const GoneError = (message = 'Gone') => {
  const err = new Error(message);
  err.statusCode = 410;
  return err;
};

const fetch = ({ requestUri }) => {
  const isGone = defined410Paths.some((pattern) => pattern.test(requestUri));
  if (isGone) {
    throw GoneError(`Content permanently removed: ${requestUri}`);
  }
  // ...normal content fetching logic
};
```

You can also throw `410` based on an API response instead of maintaining a URL list:

```js
const fetch = async ({ website_url, 'arc-site': site }) => {
  try {
    const { data } = await axios.get(
      `${CONTENT_BASE}/content/v4/?website_url=${website_url}&website=${site}`,
      { headers: { Authorization: `Bearer ${ARC_ACCESS_TOKEN}` } }
    );
    return data;
  } catch (error) {
    if (error.response?.status === 404) {
      // If you know this content was intentionally removed, return 410
      const err = new Error('Content has been permanently removed');
      err.statusCode = 410;
      throw err;
    }
    const err = new Error(error.message);
    err.statusCode = error.response?.status || 500;
    throw err;
  }
};
```

> **Caution:**
> 
> Never throw raw error objects from HTTP libraries like Axios. They may contain sensitive data such as access tokens in request headers. Always construct a new, sanitized error. See [](https://dev.arcxp.com/pagebuilder-engine/how-to-guides/components-and-content/error-handling-in-content-sources) for best practices.

### Create a custom error page for your readers to see

Without a custom error page, visitors see a bare default message (e.g., “Gone” for `410`, “Not Found” for `404`). To show a branded page for any error status code:

1. Open **PageBuilder Editor**
2. Create a new page at the path `/error/{statusCode}` (e.g., `/error/410`, `/error/404`, `/error/500`)
3. Add your standard layout features (header, navigation, footer)
4. Add a feature that displays an appropriate message for that error
5. **Publish** the page

PageBuilder Engine automatically looks for a page matching the status code and renders it. The HTTP response still returns the correct status code in the header — the custom page only controls what visitors see in the browser.

### When to use 410 vs 404

| Scenario                           | Status code |
| ---------------------------------- | ----------- |
| Content never existed at this URL  | 404         |
| Content was permanently removed    | 410         |
| Section or category shut down      | 410         |
| Temporary maintenance or unpublish | 404         |
| Content migrated to a new URL      | 301         |

## Common status codes

Here are some common status codes that PageBuilder Engine can serve which you may want custom error pages for. This list is not exhaustive — the same approach outlined above applies for any status code.

| Status Code | Meaning               |
| ----------- | --------------------- |
| 404         | Not Found             |
| 410         | Gone                  |
| 500         | Internal Server Error |
