Passer au contenu principal

Qu’est-ce qu’Inertia.js ?

Vous voulez construire votre frontend avec React ou Vue, mais éviter d’avoir à concevoir, implémenter et maintenir une API séparée ? C’est précisément la contradiction que Inertia.js vient lever. Inertia est une « glue » (colle) qui conserve le routage et les contrôleurs côté serveur tels quels, tout en vous permettant d’écrire uniquement le frontend en React, Vue ou Svelte. Ce n’est pas un framework, mais une couche d’adaptateur qui relie Laravel et les frameworks JavaScript existants.
La dernière version en date est Inertia v3 (sortie le 26 mars 2026). Les starter kits Laravel 13 (React, Vue, Svelte) sont déjà compatibles Inertia.

Différences avec les SPA/MPA classiques

ArchitectureCaractéristiquesDifficultés
MPA (application Blade classique)Simple, bonne intégration avec LaravelRechargement complet à chaque navigation
SPA (API + frontend séparés)Grande interactivitéDouble maintenance : API, authentification, types
Inertia (monolithe moderne)UX de SPA + simplicité côté serveurCoût d’apprentissage spécifique
Avec Inertia, vous transmettez directement des données depuis un contrôleur Laravel vers un composant Vue ou React. Aucune API REST à définir ; les changements de page se font en XHR plutôt qu’en rechargement complet, offrant ainsi une navigation fluide façon SPA.

Relation avec les starter kits Laravel

Lorsque vous créez un projet avec laravel new et choisissez React, Vue ou Svelte, Inertia est configuré automatiquement.
laravel new my-app
# Le prompt interactif propose React / Vue / Svelte et bascule en configuration Inertia
Le starter kit met en place automatiquement :
  • inertiajs/inertia-laravel (adaptateur côté serveur)
  • @inertiajs/react / @inertiajs/vue3 / @inertiajs/svelte (adaptateurs côté client)
  • Middleware HandleInertiaRequests
  • Écrans d’authentification (login, inscription, réinitialisation de mot de passe) déjà implémentés en composants Inertia
Pour intégrer manuellement Inertia dans un projet existant, installez séparément côté serveur et côté client. Consultez la documentation officielle pour la procédure d’installation.

Les bases de Inertia::render()

Pour renvoyer une réponse Inertia depuis un contrôleur Laravel, utilisez Inertia::render(). Le premier argument est le nom du composant JavaScript, le second les données à passer en props.
use Inertia\Inertia;

class PostController extends Controller
{
    public function index()
    {
        return Inertia::render('Posts/Index', [
            'posts' => Post::latest()->paginate(10),
        ]);
    }

    public function show(Post $post)
    {
        return Inertia::render('Posts/Show', [
            'post' => $post->only('id', 'title', 'content', 'created_at'),
            'author' => $post->user->only('id', 'name'),
        ]);
    }
}
Vous pouvez aussi utiliser la fonction helper inertia() à la place de Inertia::render(). Choisissez et harmonisez le style au sein de votre équipe.
Le nom de composant 'Posts/Index' correspond à un chemin de fichier. En React, ce sera resources/js/Pages/Posts/Index.jsx ; en Vue, resources/js/Pages/Posts/Index.vue.

Structure d’un composant de page

Les composants de page Inertia sont des composants Vue/React ordinaires. Les données passées depuis le contrôleur sont reçues comme props.
React
// resources/js/Pages/Posts/Index.jsx
import { Link } from '@inertiajs/react'

export default function PostsIndex({ posts }) {
    return (
        <div>
            <h1>Liste des articles</h1>
            {posts.data.map(post => (
                <article key={post.id}>
                    <h2>
                        <Link href={`/posts/${post.id}`}>{post.title}</Link>
                    </h2>
                </article>
            ))}
        </div>
    )
}
Vue
<!-- resources/js/Pages/Posts/Index.vue -->
<script setup>
import { Link } from '@inertiajs/vue3'

defineProps({
    posts: Object,
})
</script>

<template>
    <div>
        <h1>Liste des articles</h1>
        <article v-for="post in posts.data" :key="post.id">
            <h2>
                <Link :href="`/posts/${post.id}`">{{ post.title }}</Link>
            </h2>
        </article>
    </div>
</template>
Le composant <Link> déclenche la navigation en XHR, évitant le rechargement complet de la page. On l’écrit exactement comme une balise <a> classique, mais Inertia remplace uniquement le composant de page en coulisses.

Données partagées — middleware HandleInertiaRequests

Les données communes à toutes les pages (informations de l’utilisateur connecté, messages flash, etc.) se déclarent dans la méthode share() du middleware HandleInertiaRequests.
// app/Http/Middleware/HandleInertiaRequests.php
use Illuminate\Http\Request;
use Inertia\Middleware;

class HandleInertiaRequests extends Middleware
{
    public function share(Request $request): array
    {
        return array_merge(parent::share($request), [
            'appName' => config('app.name'),

            'auth' => [
                'user' => $request->user()
                    ? $request->user()->only('id', 'name', 'email')
                    : null,
            ],

            'flash' => [
                'success' => $request->session()->get('success'),
                'error' => $request->session()->get('error'),
            ],
        ]);
    }
}
Les données partagées sont automatiquement fusionnées avec les props de toutes les pages.
React
// Exemple d'accès depuis un composant de layout
import { usePage } from '@inertiajs/react'

export default function Layout({ children }) {
    const { auth, flash } = usePage().props

    return (
        <main>
            <header>
                {auth.user ? `Connecté : ${auth.user.name}` : 'Invité'}
            </header>
            {flash.success && <div className="alert-success">{flash.success}</div>}
            <article>{children}</article>
        </main>
    )
}
Les données partagées étant incluses dans chaque requête, il est recommandé de les limiter au strict nécessaire. Utilisez une évaluation paresseuse avec fn() pour qu’elles ne soient calculées qu’à la demande.

Envoi de formulaires et gestion des erreurs de validation

Le traitement des formulaires Inertia s’intègre naturellement à la validation Laravel. Le helper useForm() simplifie la gestion d’état, l’envoi et l’affichage des erreurs.

Côté contrôleur

class PostController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'title'   => ['required', 'string', 'max:255'],
            'content' => ['required', 'string'],
        ]);

        Post::create($validated + ['user_id' => auth()->id()]);

        return redirect()->route('posts.index')
            ->with('success', 'Article créé.');
    }
}
En cas d’erreur de validation, Laravel redirige automatiquement vers la page du formulaire et stocke les erreurs en session. Inertia les détecte et les transmet à la page via la prop errors.

Côté frontend

React
// resources/js/Pages/Posts/Create.jsx
import { useForm } from '@inertiajs/react'

export default function PostsCreate() {
    const { data, setData, post, processing, errors } = useForm({
        title: '',
        content: '',
    })

    function handleSubmit(e) {
        e.preventDefault()
        post('/posts')
    }

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <label>Titre</label>
                <input
                    value={data.title}
                    onChange={e => setData('title', e.target.value)}
                />
                {errors.title && <p className="error">{errors.title}</p>}
            </div>

            <div>
                <label>Contenu</label>
                <textarea
                    value={data.content}
                    onChange={e => setData('content', e.target.value)}
                />
                {errors.content && <p className="error">{errors.content}</p>}
            </div>

            <button type="submit" disabled={processing}>
                {processing ? 'Envoi...' : 'Publier'}
            </button>
        </form>
    )
}
Vue
<!-- resources/js/Pages/Posts/Create.vue -->
<script setup>
import { useForm } from '@inertiajs/vue3'

const form = useForm({
    title: '',
    content: '',
})

function submit() {
    form.post('/posts')
}
</script>

<template>
    <form @submit.prevent="submit">
        <div>
            <label>Titre</label>
            <input v-model="form.title" />
            <p v-if="form.errors.title" class="error">{{ form.errors.title }}</p>
        </div>

        <div>
            <label>Contenu</label>
            <textarea v-model="form.content"></textarea>
            <p v-if="form.errors.content" class="error">{{ form.errors.content }}</p>
        </div>

        <button type="submit" :disabled="form.processing">
            {{ form.processing ? 'Envoi...' : 'Publier' }}
        </button>
    </form>
</template>
En cas d’erreur de validation, useForm() conserve les données saisies tout en affichant les erreurs. L’utilisateur n’a pas à ressaisir le formulaire, ce qui améliore l’expérience.

Cas d’usage adaptés et inadaptés

Cas d’usage adaptés

  • Équipe déjà à l’aise avec Laravel qui souhaite une UI type SPA
  • Centraliser l’authentification, l’autorisation et la validation côté Laravel
  • Applications où le SEO est secondaire : back-office, outils internes, etc.
  • Projets voulant éviter le coût de conception et de gestion d’une API séparée

Cas d’usage moins adaptés

  • Plusieurs clients externes (application mobile, etc.) qui partagent la même API
  • Sites de contenu où le SEO est crucial (le SSR est possible mais plus complexe)
  • Architectures micro-frontend, ou frontend développé par une équipe totalement indépendante
Inertia prend également en charge le rendu côté serveur (SSR). Envisagez l’option SSR pour les pages où le SEO est nécessaire. Les starter kits Laravel intègrent aussi la configuration SSR.

Principales évolutions d’Inertia v3

Inertia v3 est sorti le 26 mars 2026. Voici les principaux changements par rapport à v2.

Abandon d’Axios — client XHR intégré et léger

En v3, Axios est abandonné au profit d’un client XHR intégré plus léger. La plupart des applications n’ont pas besoin de modifications. Les intercepteurs Axios se migrent directement vers les intercepteurs intégrés. Si vous souhaitez continuer à utiliser Axios, un adaptateur Axios est disponible.

Simplification du SSR avec le plugin @inertiajs/vite

Le nouveau plugin Vite simplifie fortement la résolution automatique des composants de page et la configuration SSR. En développement, le SSR fonctionne simplement avec npm run dev, sans avoir à lancer un serveur Node séparé.
npm install @inertiajs/vite@^3.0

Hook useHttp — requêtes HTTP sans changement de page

Le hook useHttp permet d’envoyer des requêtes HTTP au serveur sans déclencher de visite Inertia. Pratique pour sauvegarder une modale ou déclencher un traitement en arrière-plan tout en restant sur la page courante.

Mises à jour optimistes de l’UI (Optimistic Updates)

Les mises à jour optimistes sont prises en charge au niveau de useForm et du routeur. L’UI est mise à jour immédiatement sans attendre la réponse du serveur, avec rollback automatique en cas d’échec.

Layout Props

Le hook useLayoutProps permet à un composant de page de transmettre des données à un layout persistant. Le contrôle de l’état de layout propre à une page, auparavant possible seulement via les données partagées ou les props de page, s’écrit désormais simplement.

Changement de prérequis

Les versions minimales sont relevées en v3.
Élémentv2v3
PHP8.1+8.2+
Laravel10+11+
React18+19+
Svelte4+5+

Suppression de Inertia::lazy()

Inertia::lazy(), déprécié en v2, est complètement supprimé en v3. Utilisez Inertia::optional() à la place.
// v2 (déprécié)
'users' => Inertia::lazy(fn () => User::all()),

// v3
'users' => Inertia::optional(fn () => User::all()),

Renommage d’événements

v2v3
invalidhttpException
exceptionnetworkError

Suppression de l’option future

Le bloc de configuration expérimental future de v2 est supprimé. Toutes ces options sont désormais activées par défaut. Retirez le bloc future de la configuration de createInertiaApp.
Pour la procédure détaillée de mise à niveau depuis v2, consultez le guide de mise à niveau officiel. La v2 recevra des corrections de bugs jusqu’au 26 septembre 2026 et des correctifs de sécurité jusqu’au 26 mars 2027.

Conclusion

Inertia.js répond au besoin très concret « conserver Laravel tel quel et écrire le frontend en React/Vue ». Son plus grand atout est la simplicité : pas d’API à concevoir, les données sont passées directement du contrôleur au composant. Le fait que les starter kits Laravel 13 supportent Inertia confirme sa place dans l’écosystème Laravel. Là où Livewire construit des UI dynamiques uniquement en PHP, Inertia permet de tirer parti de la puissance des frameworks JavaScript sans sacrifier la simplicité côté serveur. Le choix dépend des compétences de l’équipe et des besoins du projet, mais lorsqu’il s’agit de « créer des écrans en React en conservant les contrôleurs Laravel », Inertia est le choix le plus naturel.

Documentation officielle Inertia.js

Retrouvez l’ensemble des fonctionnalités d’Inertia v3 dans la documentation officielle.
Dernière modification le 13 juillet 2026