next-with-error
Version:
Next.js HoC to render the Error page and send the correct HTTP status code from any page
202 lines (143 loc) • 5.13 kB
Markdown
# `next-with-error`
[](https://circleci.com/gh/martpie/next-with-error)

Next.js plugin to render the Error page and send the correct HTTP status code from any page's `getInitialProps`.
This higher-order-components allows you to easily return Next.js's Error page + the correct HTTP status code just by defining `error.statusCode` in your pages `getInitialProps`:
```jsx
// pages/something.js
const SomePage = () => (
<h1>I will only render if error.statusCode is lesser than 400</h1>
);
SomePage.getInitialProps = async () => {
const isAuthenticated = await getUser();
if (!isAuthenticated) {
return {
error: {
statusCode: 401
}
};
}
return {
// ...
};
};
```
Contents:
<!-- TOC depthfrom:2 -->
- [Installation](#installation)
- [Usage](#usage)
- [`withError([ErrorPage])(App)`](#witherrorerrorpageapp)
- [`generatePageError(statusCode[, additionalProps])`](#generatepageerrorstatuscode-additionalprops)
- [Custom error page](#custom-error-page)
- [Custom props](#custom-props)
- [Automatic Static Optimization](#automatic-static-optimization)
<!-- /TOC -->
## Installation
```bash
npm install next-with-error
```
## Usage
### `withError([ErrorPage])(App)`
Adapt `pages/_app.js` so it looks similar to [what is described in the official Next.js documentation](https://nextjs.org/docs#custom-app) and add the `withError` HoC.
<details>
<summary>Example</summary>
```jsx
// _app.jsx
import withError from 'next-with-error';
class MyApp extends App {
render() {
const { Component, pageProps } = this.props;
return <Component {...pageProps} />;
}
}
export default withError()(MyApp);
```
</details>
Then, in any of your pages, define `error.statusCode` if needed in your page's `getInitialProps`
```jsx
// pages/article.js
import React from 'react';
import fetchPost from '../util/fetch-post';
class ArticlePage extends React.Component {
static async getInitialProps() {
const article = await fetchPost();
if (!article) {
// No article found, let's display a "not found" page
// Will return a 404 status code + display the Error page
return {
error: {
statusCode: 404
}
};
}
// Otherwise, all good
return {
article
};
}
render() {
return (
<h1>{this.props.article.title}</h1>
// ...
);
}
}
export default HomePage;
```
### `generatePageError(statusCode[, additionalProps])`
If you find the code to write the error object is a bit verbose, feel free to use the `generatePageError` helper:
```jsx
import { generatePageError } from 'next-with-error';
// ...
SomePage.getInitialProps = async () => {
const isAuthenticated = await getUser();
if (!isAuthenticated) {
return generatePageError(401);
}
return {};
};
```
You can use the `additionalProps` argument to pass [custom props to the Error component](#custom-props).
### Custom error page
By default, `withError` will display the default Next.js error page. If you need to display your own error page, you will need to pass it as the first parameter of your HoC:
```jsx
import Error from './_error';
// ...
export default withError(ErrorPage)(MyApp);
```
Work to automate this [is tracked here](https://github.com/martpie/next-with-error/issues/2).
The error object properties are accessible via the `props` of your custom Error component (`props.statusCode`, `props.message`, etc if you have custom props).
⚠️ If your custom Error page has a `getInitialProps` method, the error object will be merged in `getInitialProps`'s return value. Be careful to not have conflicting names.
### Custom props
You can also pass custom props to your Error Page component by adding anything you would like in the `error` object:
```jsx
// /pages/article.js
const HomePage = () => <h1>Hello there!</h1>;
HomePage.getInitialProps = () => {
return {
error: {
statusCode: 401,
message: 'oopsie'
}
};
};
export default HomePage;
```
```jsx
// /pages/_error.js
import React from 'react';
const Error = (props) => {
return (
<>
<h1>Custom error page: {props.error.statusCode}</h1>
<p>{props.error.message}</p>
</>
);
};
export default Error;
```
⚠️ Be careful to add default values for your custom props in the `Error` component, as Next.js routing may bypass `next-with-error`'s behavior by showing the 404 page without the `message` variable (in this example).
## Automatic Static Optimization
> You have opted-out of Automatic Static Optimization due to `getInitialProps` in `pages/_app`
This plugin, like most Higher-order-Component relying on extending the `_app` file, will opt-you-out of the Automatic Static Optimization of Next.js. This is a known trade-off to avoid declaring this HoC on each one of your pages.
Things will probably change [once Next.js support for plugins will ship](https://github.com/zeit/next.js/issues/9133).