Pourquoi Inertia
Temps 1 · séance 1 · ~25 min
Les slides du chapitre (PDF)PDF
- Comparer trois façons de fabriquer une page : la page complète rendue par le serveur, l'application d'une seule page avec une API, et Inertia.
- Lire une requête Inertia dans l'onglet Réseau du navigateur.
- Dire ce que Laravel garde et ce qui change quand les pages s'écrivent en Vue.
- Reconnaître les deux parties d'un composant Vue.
- Nommer les outils du kit Vue de Laravel 13 et le rôle de chacun.
1. Trois façons de faire une page
La page complète, celle de 5XCOS
En 5XCOS, chaque clic sur un lien envoie une requête au serveur. Laravel cherche la route dans routes/web.php, appelle le contrôleur, et le contrôleur renvoie une vue Blade avec ses données.
return view('home', ['author' => 'Nora Benali']);
Blade remplace {{ $author }} par le nom et renvoie un document HTML complet : l'en-tête, la navigation, le contenu et le pied de page. Le navigateur efface la page affichée et dessine la nouvelle. Au clic suivant, il télécharge de nouveau le document entier, même si seul le contenu central a changé. Dans l'onglet Réseau des outils de développement, chaque clic ajoute une ligne de type document.
L'application d'une seule page et son API
Une SPA, pour single-page application, est une application JavaScript que le navigateur charge une seule fois. Elle dessine ensuite chaque écran elle-même, sans redemander de document HTML. Pour obtenir les données, elle appelle une API, une série d'adresses du serveur qui répondent en JSON au lieu de HTML, par exemple /api/projects.
Ce découpage a un prix. Vous écrivez deux projets : l'API en Laravel et l'interface en JavaScript. Les adresses existent deux fois, côté serveur pour l'API et côté navigateur pour les écrans. Les erreurs de validation arrivent en JSON, et votre code JavaScript doit les placer lui-même sous chaque champ. La connexion demande aussi un mécanisme à part, souvent un jeton, une chaîne secrète que le navigateur joint à chaque requête.
Inertia, entre les deux
Inertia est une bibliothèque qui relie un contrôleur Laravel à une page écrite en Vue. Le contrôleur ne renvoie plus une vue Blade. Il renvoie le nom d'une page Vue et les données qu'elle doit afficher.
return Inertia::render('Home', ['author' => 'Nora Benali']);
'Home' désigne le fichier resources/js/pages/Home.vue. Le tableau contient les props, les données que le contrôleur transmet à la page. Au premier chargement, Laravel renvoie un document HTML qui contient le nom de la page et ses props. Vue lit ces données et dessine la page dans le navigateur. Aux clics suivants, Inertia demande seulement le JSON de la nouvelle page, et Vue remplace la page affichée sans recharger le document.
Vous gardez un seul projet Laravel, avec ses routes, ses contrôleurs et sa validation. La navigation ressemble à celle d'une SPA, et vous n'écrivez aucune API.
| Page complète (Blade) | SPA et API | Inertia | |
|---|---|---|---|
| Qui fabrique le HTML | le serveur, à chaque clic | le navigateur | le navigateur, avec les props envoyées par le serveur |
| Ce qui arrive après un clic | le document HTML entier | du JSON, demandé par votre code JavaScript | du JSON, demandé par Inertia |
| Les adresses | routes/web.php |
deux fois : l'API et les écrans | routes/web.php |
| La validation | le contrôleur ou une Form Request | le serveur, plus l'affichage des erreurs à coder | le contrôleur ou une Form Request |
| Les projets à maintenir | un | deux | un |

2. Une requête Inertia dans l'onglet Réseau
La route de la page d'accueil d'un portfolio d'exemple appelle Inertia::render('Home', ['author' => 'Nora Benali']), la ligne de la section 1.
Le premier chargement
Au premier chargement, le navigateur reçoit un document HTML, comme avec Blade. Ouvrez le code source de la page avec Ctrl+U, ou Cmd+Option+U sur macOS. Vers la fin du document, une balise <script> contient les données de la page en JSON.
<script data-page="app" type="application/json">{"component":"Home","props":{"errors":{},"name":"Laravel","auth":{"user":null},"sidebarOpen":true,"author":"Nora Benali"},"url":"\/","version":"4927d70f24a6b79ccc312d79f1e3bc91","sharedProps":["errors","name","auth","sidebarOpen"]}

Ce JSON s'appelle l'objet de page. Inertia le lit au démarrage pour savoir quelle page Vue dessiner et avec quelles données.
| Clé | Ce qu'elle contient |
|---|---|
component |
le nom de la page, ici Home pour resources/js/pages/Home.vue |
props |
les données de la page : author, envoyée par la route, et quatre autres ajoutées à toutes les pages |
url |
l'adresse de la page |
version |
une empreinte des fichiers compilés par Vite |
sharedProps |
la liste des props ajoutées à toutes les pages : errors, name, auth, sidebarOpen |
Une prop partagée est une donnée que le serveur ajoute à chaque page. Le kit en déclare trois : name, le nom de l'application, auth, l'utilisateur connecté ou null, et sidebarOpen, l'état de la barre latérale du back-office. Inertia ajoute errors, qui recevra les erreurs de validation de vos formulaires.
Tout ce JSON est lisible par n'importe quel visiteur. Une prop n'est jamais secrète. Au chapitre 1.07, vous choisirez donc avec soin ce que vous envoyez à une page.
Les clics suivants
Au chapitre 1.08, vous écrirez des liens Inertia avec le composant <Link>. Quand un visiteur clique sur un tel lien, le navigateur ne demande plus de document. Inertia envoie une requête en arrière-plan avec, entre autres, deux en-têtes, des lignes d'information jointes à la requête.
X-Inertia: true
X-Inertia-Version: 4927d70f24a6b79ccc312d79f1e3bc91

X-Inertia: true dit à Laravel que la requête vient d'Inertia. Laravel exécute la même route et le même contrôleur qu'au premier chargement. Il renvoie cette fois l'objet de page seul, en JSON, sans le document HTML autour. Laravel répond avec ces en-têtes et ce contenu.
HTTP/1.1 200 OK
X-Inertia: true
Content-Type: application/json
Vary: X-Inertia
{"component":"Home","props":{"errors":{},"name":"Laravel","auth":{"user":null},"sidebarOpen":true,"author":"Nora Benali"},"url":"\/","version":"4927d70f24a6b79ccc312d79f1e3bc91","sharedProps":["errors","name","auth","sidebarOpen"]}
Vue reçoit ce JSON, cherche le composant Home et le dessine avec ses props. L'adresse change dans la barre du navigateur, mais le document n'est pas rechargé.
Après le chapitre 1.04, vous verrez cette requête sur votre portfolio. Ouvrez /login, puis les outils de développement avec F12, et choisissez l'onglet Réseau. Cliquez sur le filtre « Fetch/XHR », puis sur « Forgot your password? » : ce lien du kit est un lien Inertia. Une ligne apparaît. Son onglet « En-têtes » montre X-Inertia: true, et son onglet « Réponse » montre le JSON. Les captures de ce cours montrent les outils en anglais : Network, Headers et Response.
Quand la version ne correspond plus
L'en-tête X-Inertia-Version porte l'empreinte des fichiers compilés que le navigateur utilise. Cette empreinte change à chaque npm run build, la commande qui compile ces fichiers, par exemple avant une mise en ligne. Si la version envoyée ne correspond plus à celle du serveur, Laravel ne renvoie pas le JSON.
HTTP/1.1 409 Conflict
X-Inertia-Location: …
X-Inertia-Version: 27788163fbbd39eaf69368cad25b982c
Le code 409 signale le conflit, et X-Inertia-Location donne l'adresse demandée. X-Inertia-Version donne cette fois la version du serveur, différente de celle que le navigateur a envoyée. Inertia recharge alors cette adresse comme un document complet, avec les nouveaux fichiers. Le visiteur ne voit qu'un rechargement normal.
3. Ce que Laravel garde, ce qui change
Presque tout ce que vous avez appris en 5XCOS reste en place. Les routes s'écrivent dans routes/web.php et appellent des contrôleurs. Une Form Request valide les données d'un formulaire. Les sessions gardent l'utilisateur connecté entre deux pages. Les modèles Eloquent, les migrations, les seeders et les tests Pest fonctionnent comme avant.
Ce qui change, c'est la fabrication de la page. Une seule vue Blade reste dans le projet : resources/views/app.blade.php, la vue racine, le document HTML dans lequel chaque page Vue s'affiche. Deux de ses lignes font le lien avec Vue.
@vite(['resources/css/app.css', 'resources/js/app.ts', "resources/js/pages/{$page['component']}.vue"])
<x-inertia::app />
La directive @vite charge le CSS, le fichier de démarrage app.ts et le fichier de la page demandée. $page['component'] vaut Home pour la page d'accueil, si bien que Vite charge resources/js/pages/Home.vue. Le composant <x-inertia::app /> place l'objet de page dans le document, sous la forme de la balise <script data-page> de la section 2.
| En 5XCOS, avec Blade | Avec Inertia et Vue |
|---|---|
return view('home', [...]) |
return Inertia::render('Home', [...]) |
une vue par page dans resources/views |
un composant Vue par page dans resources/js/pages |
des variables dans la vue, comme $author |
des props déclarées par la page, comme author |
des liens <a href> |
des liens <Link>, au chapitre 1.08 |
un formulaire <form> avec @csrf |
le composant <Form> d'Inertia, au chapitre 1.12 |
Vite doit aussi tourner pendant que vous travaillez, lancé par composer run dev. Chaque page est un fichier que Vite prépare pour le navigateur, et une page nouvelle n'existe pas tant que Vite ne l'a pas vue. Vous le constaterez au chapitre suivant.
4. Un composant Vue
Un composant Vue est un fichier .vue qui regroupe le JavaScript et le HTML d'un morceau de page. Une page Inertia est un composant placé dans resources/js/pages. Voici la page d'accueil du portfolio d'exemple.
<script setup>
defineProps({
author: String,
});
</script>
<template>
<h1>Bonjour, je suis {{ author }}</h1>
</template>
Le fichier a deux parties. Le bloc <script setup> contient le JavaScript du composant. Ici, defineProps déclare les props que la page accepte : une seule, author, qui doit être une chaîne de caractères. Le nom correspond à la clé 'author' du tableau passé à Inertia::render.
Le bloc <template> contient le HTML de la page. Les doubles accolades affichent la valeur d'une prop, comme {{ $author }} dans Blade, mais sans le $. Vue échappe aussi le texte affiché, comme Blade.
La page affiche donc « Bonjour, je suis Nora Benali ». Les boucles et les conditions, v-for et v-if, arrivent au chapitre 1.07 avec la liste de vos projets.
5. Le kit Vue de Laravel 13
Le kit, vous le savez depuis le chapitre 0, est le projet de départ que laravel new crée avec Vue. Il réunit sept outils.
| Outil | Son rôle dans votre portfolio |
|---|---|
| Vue 3 | dessine les pages et les composants dans le navigateur. |
| Inertia 3 | relie les contrôleurs aux pages : Inertia::render côté PHP, le paquet @inertiajs/vue3 côté navigateur. |
| Tailwind CSS 4 | met les pages en forme, comme en 5XCOS. Sa configuration se trouve dans resources/css/app.css. |
| shadcn-vue | fournit des composants d'interface, comme un bouton, un champ ou une carte, copiés dans resources/js/components/ui. Ils vous appartiennent, vous les modifiez comme votre code, au chapitre 1.11. |
| Fortify | gère la connexion côté serveur : se connecter, réinitialiser un mot de passe, vérifier une adresse e-mail. Vous fermerez l'inscription au chapitre 1.10. |
| Wayfinder | fabrique à partir de vos routes des fonctions qui donnent leur adresse. Si une adresse change dans routes/web.php, les liens suivent, au chapitre 1.08. |
| Pest | lance les tests. Le kit arrive avec 40 tests qui passent, sur la connexion et les réglages du compte. |
Le kit contient aussi un back-office de départ, avec une barre latérale, un tableau de bord et les pages de réglages du compte. Votre portfolio s'en servira à la séance 3.
6. TypeScript dans le kit, JavaScript dans vos fichiers
Le kit est écrit en TypeScript, le JavaScript avec des types présenté au chapitre 0. Ses pages commencent par <script setup lang="ts">, et son fichier de démarrage s'appelle app.ts. Vous gardez ces fichiers tels quels : vous les lisez, vous ne les réécrivez pas.
Dans les pages et les composants que vous ajoutez, vous écrivez du JavaScript. Vos fichiers commencent par <script setup>, sans lang="ts", comme l'exemple de la section 4. Les deux langages cohabitent dans le même projet, et Vite prépare les deux pour le navigateur.
À retenir
- Une page Blade est fabriquée par le serveur à chaque clic, une SPA se dessine dans le navigateur avec les données d'une API.
- Avec Inertia, le contrôleur renvoie
Inertia::render('Page', [...])et Vue dessine la page avec ces props. - Après le premier chargement, une requête Inertia porte l'en-tête
X-Inertia: trueet reçoit l'objet de page en JSON. - Les props sont lisibles par tout visiteur dans le code source et dans l'onglet Réseau.
- Un composant Vue a un bloc
<script setup>en JavaScript et un bloc<template>en HTML.
Ce que vous faites maintenant
Au chapitre 1.04, vous créez votre portfolio avec le kit Vue. Vous écrivez votre première route, votre première page et votre première prop : votre nom.