A 404 page may be accessed very often so Blitz provides a static 404 page by default without having to add any additional files.
To create a custom 404 page you can create a app/pages/404.js
file. This
file is statically generated at build time.
// app/pages/404.js
export default function Custom404() {
return <h1>404 - Page Not Found</h1>
}
By default Blitz provides a 500 error page that matches the default 404 page’s style. This page is not statically optimized as it allows server-side errors to be reported. This is why 404 and 500 (other errors) are separated.
500 errors are handled both client-side and server-side by the Error
component. If you wish to override it, define the file
app/pages/_error.js
and add the following code:
function Error({ statusCode }) {
return (
<p>
{statusCode
? `An error ${statusCode} occurred on server`
: "An error occurred on client"}
</p>
)
}
Error.getInitialProps = ({ res, err }) => {
const statusCode = res ? res.statusCode : err ? err.statusCode : 404
return { statusCode }
}
export default Error
app/pages/_error.js
is only used in production. In development you’ll get an error with the call stack to know where the error originated from.
The default app/pages/_app.tsx
configures an error boundary which
catches errors that happen during render, on the client side. This will
also catch errors within useQuery
or useMutation
because they happen
in suspense.
In essence, the default configuration is:
export default function App({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} {...etc}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
The RootErrorFallback
is rendered when a error happens within render, or
a suspended mutation or query. By default:
function RootErrorFallback({
error,
resetErrorBoundary,
}: ErrorFallbackProps) {
if (error instanceof AuthenticationError) {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error instanceof AuthorizationError) {
return (
<ErrorComponent
statusCode={error.statusCode}
title="Sorry, you are not authorized to access this"
/>
)
} else {
return (
<ErrorComponent
statusCode={error.statusCode || 400}
title={error.message || error.name}
/>
)
}
}
If your query, mutation, or render function
throw new AuthenticationError()
when the user is not authenticated, you
can detect that within the error fallback:
function RootErrorFallback({
error,
resetErrorBoundary,
}: ErrorFallbackProps) {
if (error instanceof AuthenticationError) {
return <MyCustomError error={error} onRetry={resetErrorBoundary} />
}
return (
<ErrorComponent
statusCode={error.statusCode || 400}
title={error.message || error.name}
/>
)
}
Your query, mutation, or render function may call
throw new AuthorizationError()
when a user is authenticated but not
authorized to do something. The error fallback may handle that:
function RootErrorFallback({
error,
resetErrorBoundary,
}: ErrorFallbackProps) {
if (error instanceof AuthorizationError) {
return <MyCustomError error={error} onRetry={resetErrorBoundary} />
}
return (
<ErrorComponent
statusCode={error.statusCode || 400}
title={error.message || error.name}
/>
)
}
You can render the built-in error page by importing ErrorComponent
.
It accepts two props:
statusCode
- a number to display as the error codetitle
- a string to display as the error messageimport { ErrorComponent } from "blitz"
export default function Page() {
return <ErrorComponent statusCode={404} />
}
import { ErrorComponent } from "blitz"
export default function Page() {
return <ErrorComponent statusCode={401} title="Unauthorized" />
}