11 décembre 2025   |   De Jérôme Borg   |    Laravel, Vue

Laravel Inertia Vue3js

Laravel Inertia Vue3js

Dans le développement web, on distingue plusieurs architectures de site web :

Les applications monolithiques, le front et le back sont contenus dans la même application. Typiquement, laravel + blade.
Laravel génère des pages html à la demande et s'appuie sur le moteur de templatage blade.
A chaque demande du client (request), le serveur renvoie (response) le contenu (la data) et le contenant (html/css).

Les applications front en javascript (react, vue js...). L'application contient tout le contenant et les logiques d'appel au back.
Le back est une api. A chaque demande du client (le front), on appelle une route d'api (endpoint), ex https://application.test/api/books.
Le serveur ne va renvoyer que les données sous formatées en json.

Dans l'écosystème Laravel, nous avons la possibilité d'utiliser la bibliothèque Inertia js, qui va faire le liant entre le back et le front.
Le back et le front seront dans la même application, mais le front sera une application embarquée dans laravel en react ou vue js ou svelte.
De la même manière que le mode application Front qui fait appel à une api, Inertia, grâce à ses helpers, va nous permettre de passer beaucoup plus de données et de conserver des états. Comme par exemple, les routes de laravel, ou des objets useForm, très utiles pour la gestion des formulaires.

On peut installer inertia manuellement, ou utiliser les starter kits de laravel.

https://inertiajs.com/

 

Les starters kit de laravel


https://laravel.com/starter-kits

Laravel nous met à disposition 3 nouveaux starter kit.

Laravel / react (avec inertia)

Laravel / vuejs (avec inertia)

Laravel / livewire (php avec une surcouche javascript)

Il n'y a pas de nouveau starter kit pour blade, mais on peut toujours utiliser laravel/breeze

https://laravel.com/docs/10.x/starter-kits

Examinons plus en détail l'installation de laravel avec vuejs

Pour bénéficier du choix dans l'installation, il faut installer l'application laravel

composer global require laravel/installer

ensuite il suffit de saisir la commande

laravel new nom-de-votre-projet

Laravel nous demande le type de stack que nous souhaitons installer

puis le type d'authentification, le plus simple est de sélectionner le mode intégré de laravel

ensuite le framework pour les tests

enfin, si l'on souhaite utiliser le package "boost" pour l'IA

Finalement, laravel va installer toutes les dépendances php

Vu que nous utilisons un starter kit, certaines pages sont déjà présentes, comme toute la gestion de l'authentification (login, register, lostpassword) et la gestion de son profil. Ces pages sont regroupées dans le dossier resources/js

On remarque à la racine deux fichiers particuliers, app.ts et ssr.ts.

app.ts va englober toute notre application front

ssr.ts va faire de même mais conserver cette application sur le serveur afin de pouvoir être référencée correctement par les moteurs de recherche.

Voici le contenu du fichier app.ts

Il contient le noyau d'inertia, et l'initialisation de l'application.

Une fois que notre application sera "buildée", elle sera automatiquent "bindée" dans le fichier resources/views/app.blade.php grâce aux directives blade, @inertiaHead et @inertia, ainsi inertia fait le lien entre le front et le back.

 

Coté back on conserve le routeur web laravel

use App\Http\Controllers\ContactController;

Route::get('/contact', [ContactController::class, 'index'])->name('contact.index');
Route::post('/contact', [ContactController::class, 'store'])->name('contact.store');

 

Ziggy

Jusqu'à récemment, les routes pouvaient être récupérées coté front, grâce à l'helper route et avec comme paramètre la route nommée.
Ce principe est très efficace, car en cas de changement d'url, la route nommée ne change pas et laravel retrouvera l'url.
Les routes pouvaient être récupérées par le front car elles étaient toutes envoyées au front grâce la bibliothèque ziggy et le middleware HandleInertiaRequest

Ce middleware permet entre-autre via la méthode share de partager des informations entre le back et le front, à chaque request 

    public function share(Request $request): array
    {
        try {
            return [
                ...parent::share($request),
                'name' => Inertia::once(static fn() => config('app.name')),
                'auth' => [
                    'user' => $request->user('web')?->only('id', 'name', 'firstname', 'email', 'role', 'fullName'),
                ],
                'ziggy' => [
                    ...(new Ziggy)->toArray(),
                    'location' => $request->url(),
                ],
                'env' => Inertia::once(static fn() => config('app.env')),
                'url' => Inertia::once(static fn() => config('app.url')),
                ...
                
            ];
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
            Log::error($e->getMessage(), $e->getCode());
        }
        return [];
    }

il faut modifier le fichier resources/js/app.ts, afin d'importer ziggy

import { ZiggyVue } from 'ziggy-js';
...
.use(ZiggyVue)

Par exemple je veux créer un bouton qui pointe sur la page contact

<script setup lang="ts">

import { Link } from '@inertiajs/vue3';

</script>

<template>
    <main>
            <nav class="flex items-center justify-center gap-4">
                            <Link :href="route('contact.index')">{{
                                Contact-us
                            }}</Link>
                    </div>
            </nav>
    </main>
</template>

 

wayfinder

A présent laravel utilise le package laravel/wayfinder

https://github.com/laravel/wayfinder

"Laravel Wayfinder assure une transition fluide entre votre backend Laravel et votre frontend TypeScript. Il génère automatiquement des fonctions TypeScript entièrement typées et importables pour vos contrôleurs et routes, vous permettant ainsi d'appeler vos points de terminaison Laravel directement dans votre code client, comme n'importe quelle autre fonction. Fini les URL codées en dur, les paramètres de route à deviner et la synchronisation manuelle des modifications du backend."

A chaque création de routes dans le fichier routes/web, wayfinder va générer automatiquement, des fichiers typescript, contenant des informations de la route créée dans le dossier resources/js/routes

Comme par exemple pour les routes de contact

resources/js/routes/contact/index.ts

A présent le même exemple que plus haut mais avec wayfinder

<script setup lang="ts">

import { Link } from '@inertiajs/vue3';
// import des routes pour contact
import contact from '@/routes/contact';

</script>

<template>
    <main>
            <nav class="flex items-center justify-center gap-4">
                            <Link :href="contact.index()">{{
                                Contact-us
                            }}</Link>
                    </div>
            </nav>
    </main>
</template>

Dans cet exemple j'ai importé toutes les routes présentes pour contact, contact.index et contact.store dans l'objet contact.

On peut n'importer qu'une seule route, comme par exemple dans le formulaire de soumission de la page contact, je n'ai mis qu'un extrait de code avec un seul champ

<script setup lang="ts">
import InputError from '@/components/InputError.vue';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Spinner } from '@/components/ui/spinner';
import { Textarea } from '@/components/ui/textarea';
import AuthBase from '@/layouts/AuthLayout.vue';
// import de la route de soumission en post
import { store } from '@/routes/contact';
import { Form } from '@inertiajs/vue3';

</script>

<template>
    <AuthBase>

        <Form
            v-bind="store.form()" <!-- utilisation la méthode store sur notre formulaire -->
            v-slot="{ errors, processing }"
            class="flex flex-col gap-6"
            resetOnSuccess
        >
            <div class="grid gap-6">

                <div class="grid gap-2">
                    <Label for="message">Message</Label>
                    <Textarea
                        id="message"
                        required
                        name="message"
                        placeholder="Message"
                    />
                    <InputError :message="errors.message" />
                </div>

                <Button
                    type="submit"
                    class="mt-2 w-full"
                    tabindex="6"
                    :disabled="processing"
                    data-test="register-user-button"
                >
                    <Spinner v-if="processing" />
                    Send
                </Button>
            </div>
        </Form>
    </AuthBase>
</template>

 

 

De Jérôme Borg
Le 11 décembre 2025
Temps de lecture : 15 min
Jérôme Borg
Jérôme Borg

Développeur fullstack laravel/VueJs, formateur

Tous les articles de cet auteur
Articles recommandés
Installer Laravel 12
Installer Laravel 12
Jérôme Borg De Jérôme Borg | 15 mars 2025 | Lu : 5min