The error pages with Laravel and InertiaJS
2 min read

The error pages with Laravel and InertiaJS

By design, Laravel handles automatically the error pages. They are detailed in development mode and 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 Compendium on it, which can be available in early access to people registered on this website (translation in progress) :

EARLY ACCESS - Compendium Laravel
Laravel est un framework PHP tout-en-un qui propose de nombreux éléments pour les développeurs d’application web et qui est très orienté. Il se veut accessible aux débutants et developer-friendly avec notamment des outils reconnus comme Eloquent.

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 sam 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()])
            ->toResponse($request)
            ->setStatusCode($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.

Like 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...

<template>
    <app-layout :public-site="true">
        <div v-if="status === 404">
            <div class="container">
                <div>
                    <div>
                        <h1>404</h1>
                        <h2>Are you lost... ?</h2><br>
                        <p>Don't worry...<br/>
                            <strong>We can help you find a home !</strong></p>
                        <a :href="route('find-a-home')" class="mt-4">Find a home now !</a>
                    </div>
                </div>
            </div>
        </div>
        <div v-else>
            <h1>{{ title }}</h1>
            <div>{{ description }}</div>
        </div>
    </app-layout>
</template>

<script>
import AppLayout from "@/Layouts/AppLayout";
export default {
    components: {AppLayout},
    props: {
        status: Number,
    },
    computed: {
        title() {
            return {
                503: '503: Service Not Available',
                500: '500: Error',
                403: '403: Access refused',
            }[this.status]
        },
        description() {
            return {
                503: "Sorry, we are operationg a maintenance. Come back later.",
                500: 'Oups, an error occured.',
                403: "Sorry, you are not allowed to access this content.",
            }[this.status]
        },
    },
}
</script>

Vous aimez mes articles? Inscrivez-vous pour être alerté des nouveautés.