Article
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. There is also another article on the subject: Translate Laravel Jetstream and Inertia.
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()])
->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.
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...
<template>
<app-layout :public-site="true">
<div v-if="status === 404">
<div class="container">
<div>
<div>
<h1>404</h1>
<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>
</div>
</div>
</div>
<div v-else>
<h1>noparse_b7f3919a99d4093361004e8fd25d5a1e</h1>
<div>noparse_e976016c7fa0a88cf04d9d783cbd57e1</div>
</div>
</app-layout>
</template>
<script>
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é',
}[this.status]
},
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.",
}[this.status]
},
},
}
</script>