Aller au contenu

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

Trois façons de faire une page : le serveur renvoie le HTML à chaque clic, une SPA appelle une API en JSON, Inertia renvoie le HTML une fois puis le JSON de chaque page

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"]}

Le code source de la page d'accueil, avec la balise script data-page qui contient l'objet de page en JSON

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

L'onglet Réseau de Chrome, filtre Fetch/XHR, après un clic sur un lien Inertia : une seule requête, projets, avec X-Inertia: true dans les en-têtes de requête

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: true et 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.