Statamic Peak


The error pages with Laravel and InertiaJS

How to customize error pages with Laravel and InertiaJs ? It's all you need to know !

By design, Laravel handles automatically the error pages. They are detailed in development mode and contains informations on the error causes. In production mode, they are very generic and only contains a message, preventing a data leak.

By adding Inertia, the default Laravel running does not exactly fit. As errors are not Inertia responses, they are opened into a modal, which doesn't really makes sense.

We will then make modifications to get a true redirection to a personalized page!

If you're interested in Laravel, I'm preparing a Laravel Compendium, which can be available in early access.

Display an Inertia response as a Laravel error

The Inertia documentation explains the process. We add a render function to our App\Exception\Handler.php, the same class we would modify if we added a tool like Sentry or Flare.

use Throwable;
use Inertia\Inertia;

 * Prepare exception for rendering.
 * @param  \Throwable  $e
 * @return \Throwable
public function render($request, Throwable $e)
    $response = parent::render($request, $e);

    if (!app()->environment(['local', 'testing']) && in_array($response->status(), [500, 503, 404, 403])) {
        return Inertia::render('Error', ['status' => $response->status()])
    } else if ($response->status() === 419) {
        return back()->with([
            'message' => __('The page expired, please try again.'),

    return $response;

In this function, we get the default Laravel response. If we are in development mode, we simply throw it back and get a display of the Ignition view into a modal. In production mode, we throw an Inertia response that we can customize.

As always in Inertia, we specify in Inertia::render the name of the component we want to display. In our example, it is the resources/js/Pages/Error.vue file.

Then, because it is a classic Inertia response and a Vue component, wee can do whatever we want : get datas from the server as props, translate the content, etc...

    <app-layout :public-site="true">
        <div v-if="status === 404">
            <div class="container">
                        <h2>Vous êtes perdu... ?</h2>
                        <p>Ne vous inquiétez pas...<br/>
                            <strong>Nous pouvons tout de même vous aider à trouver une maison !</strong></p>
                        <a :href="route('find-a-home')" class="mt-4">Trouver une maison maintenant !</a>
        <div v-else>

import AppLayout from "@/Layouts/AppLayout";
export default {
    components: {AppLayout},
    props: {
        status: Number,
    computed: {
        title() {
            return {
                503: '503: Service Indisponible',
                500: '500: Erreur',
                403: '403: Accès refusé',
        description() {
            return {
                503: "Désolé, nous sommes en train d'effectuer une maintenance. Revenez plus tard.",
                500: 'Oups, une erreur est survenue.',
                403: "Désolé, vous n'avez pas accès à cette page.",