Vai al contenuto principale

Cos’è Inertia.js

Vuoi realizzare il frontend con React o Vue. Ma vuoi evitare di progettare, implementare e mantenere un’API a parte: la soluzione a questo dilemma è Inertia.js. Inertia lascia intatti il routing e i controller lato server e ti permette di scrivere solo il frontend in React, Vue o Svelte, funzionando come una “colla”. Non è un framework, ma un livello adattatore che collega Laravel esistente e i framework JavaScript.
L’ultima versione attuale è Inertia v3 (rilasciata il 26 marzo 2026). Gli starter kit di Laravel 13 (React, Vue, Svelte) sono già compatibili con Inertia.

Differenze rispetto a SPA e MPA tradizionali

ArchitetturaCaratteristicheProblemi
MPA (app Blade tradizionale)Semplice, facile da integrare con LaravelFull reload a ogni transizione di pagina
SPA (API + frontend separati)Alta interattivitàDoppia gestione di design API, autenticazione e definizioni dei tipi
Inertia (monolite moderno)UX di SPA + semplicità lato serverHa un costo di apprendimento proprio
Usando Inertia puoi passare dati direttamente dai controller Laravel ai componenti Vue o React. Non è necessario definire un’API REST e anche le transizioni di pagina avvengono via XHR anziché con full reload del browser, ottenendo una sensazione fluida da SPA.

Relazione con gli starter kit Laravel

Quando crei un progetto con laravel new e scegli React, Vue o Svelte, Inertia viene configurato automaticamente.
laravel new my-app
# Il prompt interattivo con React / Vue / Svelte crea una configurazione Inertia
Negli starter kit viene predisposto automaticamente quanto segue.
  • inertiajs/inertia-laravel (adapter lato server)
  • @inertiajs/react / @inertiajs/vue3 / @inertiajs/svelte (adapter lato client)
  • Middleware HandleInertiaRequests
  • Schermate di autenticazione come login, registrazione e reset password (già implementate come componenti Inertia)
Per introdurre Inertia manualmente in un progetto esistente, installa separatamente lato server e lato client. Per i dettagli fai riferimento alle istruzioni di installazione della documentazione ufficiale.

Le basi di Inertia::render()

Per restituire una risposta Inertia da un controller Laravel usa Inertia::render(). Come primo argomento specifichi il nome del componente JavaScript, come secondo i dati da passare come prop.
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'),
        ]);
    }
}
In alternativa a Inertia::render() puoi usare la funzione helper inertia(). Quale usare va uniformato allo stile del team.
Il nome del componente 'Posts/Index' corrisponde a un percorso di file. In React è resources/js/Pages/Posts/Index.jsx, in Vue resources/js/Pages/Posts/Index.vue.

Struttura del componente di pagina

I componenti di pagina di Inertia sono normali componenti Vue/React. I dati passati dal controller vengono ricevuti come prop.
React
// resources/js/Pages/Posts/Index.jsx
import { Link } from '@inertiajs/react'

export default function PostsIndex({ posts }) {
    return (
        <div>
            <h1>Elenco dei post</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>Elenco dei post</h1>
        <article v-for="post in posts.data" :key="post.id">
            <h2>
                <Link :href="`/posts/${post.id}`">{{ post.title }}</Link>
            </h2>
        </article>
    </div>
</template>
Con il componente <Link> le transizioni avvengono via XHR, evitando il full reload della pagina. Si scrive esattamente come un normale tag <a>, ma dietro le quinte Inertia sostituisce solo il componente di pagina.

Dati condivisi — middleware HandleInertiaRequests

I dati necessari a tutte le pagine (utente loggato, messaggi flash, ecc.) si definiscono nel metodo share() del 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'),
            ],
        ]);
    }
}
I dati condivisi vengono mergiati automaticamente nelle prop di tutte le pagine.
React
// Esempio di accesso da un componente Layout
import { usePage } from '@inertiajs/react'

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

    return (
        <main>
            <header>
                {auth.user ? `Loggato come: ${auth.user.name}` : 'Ospite'}
            </header>
            {flash.success && <div className="alert-success">{flash.success}</div>}
            <article>{children}</article>
        </main>
    )
}
Poiché i dati condivisi sono inclusi in ogni richiesta, ti consigliamo di limitarli allo stretto necessario. Se usi valutazioni lazy con fn(), verranno valutati solo nelle richieste che li richiedono davvero.

Invio dei form e gestione degli errori di validazione

La gestione dei form con Inertia si integra naturalmente con la validazione di Laravel. Usando l’helper useForm() puoi implementare in modo semplice la gestione dello stato, l’invio e la visualizzazione degli errori.

Lato controller

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', 'Post creato con successo.');
    }
}
In caso di errore di validazione, Laravel reindirizza automaticamente alla pagina del form e salva le informazioni sull’errore in sessione. Inertia lo rileva automaticamente e passa i dati alla pagina come prop errors.

Lato 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>Titolo</label>
                <input
                    value={data.title}
                    onChange={e => setData('title', e.target.value)}
                />
                {errors.title && <p className="error">{errors.title}</p>}
            </div>

            <div>
                <label>Contenuto</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 ? 'Invio in corso...' : 'Pubblica'}
            </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>Titolo</label>
            <input v-model="form.title" />
            <p v-if="form.errors.title" class="error">{{ form.errors.title }}</p>
        </div>

        <div>
            <label>Contenuto</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 ? 'Invio in corso...' : 'Pubblica' }}
        </button>
    </form>
</template>
Quando arrivano errori di validazione, useForm() mostra gli errori mantenendo i contenuti inseriti. Non serve reinserire tutto e l’esperienza utente migliora.

Casi d’uso adatti e non adatti

Casi in cui Inertia è adatto

  • Team che conoscono bene Laravel e vogliono realizzare UI in stile SPA
  • Volere gestire in modo centralizzato lato Laravel autenticazione, autorizzazione e validazione
  • App con SEO non prioritario, come pannelli di amministrazione o strumenti interni
  • Progetti in cui vuoi evitare il costo di progettare e mantenere un’API separata

Casi in cui non è adatto

  • Quando più client esterni (app mobile, ecc.) usano la stessa API
  • Siti di contenuti in cui la SEO è molto importante (gestibile con SSR ma complesso)
  • Configurazioni micro-frontend, in cui il frontend è sviluppato da team completamente indipendenti
Inertia supporta anche il Server-Side Rendering (SSR). Se ci sono pagine che richiedono SEO, considera l’opzione SSR. Anche gli starter kit di Laravel includono la configurazione SSR.

Principali modifiche di Inertia v3

Inertia v3 è stato rilasciato il 26 marzo 2026. Ecco le principali novità rispetto a v2.

Rimozione di Axios — verso un client XHR integrato leggero

In v3 Axios è stato rimosso e sostituito da un client XHR integrato più leggero. Nella maggior parte delle applicazioni non serve modificare il codice. Gli interceptor di Axios possono essere migrati direttamente sugli interceptor integrati. Se vuoi continuare a usare Axios, puoi farlo tramite un adapter Axios.

Semplificazione dell’SSR con il plugin @inertiajs/vite

Introducendo il nuovo plugin Vite, la risoluzione automatica dei componenti di pagina e la configurazione SSR risultano notevolmente semplificate. L’SSR in sviluppo funziona semplicemente eseguendo npm run dev, senza dover avviare un server Node separato.
npm install @inertiajs/vite@^3.0

Hook useHttp — richieste HTTP senza transizione di pagina

Con l’hook useHttp puoi inviare richieste HTTP al server senza generare una transizione (visit Inertia). Utile quando vuoi comunicare mantenendo la pagina corrente, come per il salvataggio da un modale o per elaborazioni in background.

Aggiornamenti UI ottimistici (Optimistic Updates)

Sono supportati gli aggiornamenti ottimistici a livello di useForm e di router. La UI viene aggiornata immediatamente senza attendere la risposta del server e, in caso di fallimento, viene automaticamente rollbackata.

Layout Props

Con l’hook useLayoutProps puoi passare dati da un componente di pagina a un layout persistente. Il “controllo dello stato del layout per una pagina specifica”, che prima poteva basarsi solo sui dati condivisi o sulle prop di pagina, ora si scrive in modo semplice.

Cambiamenti nei requisiti

In v3 sono state innalzate le versioni minime seguenti.
Elementov2v3
PHP8.1+8.2+
Laravel10+11+
React18+19+
Svelte4+5+

Rimozione di Inertia::lazy()

Inertia::lazy(), deprecato in v2, è stato completamente rimosso in v3. Al suo posto si usa Inertia::optional().
// v2 (deprecato)
'users' => Inertia::lazy(fn () => User::all()),

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

Rinomina degli eventi

v2v3
invalidhttpException
exceptionnetworkError

Rimozione dell’opzione future

Il blocco di configurazione future, fornito in v2 come opzione sperimentale, è stato rimosso. Tutte quelle opzioni sono ora abilitate per impostazione predefinita. Rimuovi il blocco future dalla configurazione di createInertiaApp.
Per i dettagli sulla procedura di aggiornamento da v2 consulta la guida ufficiale di aggiornamento. Per v2 le bug fix sono fornite fino al 26 settembre 2026 e le correzioni di sicurezza fino al 26 marzo 2027.

Conclusioni

Inertia.js è uno strumento che risponde all’esigenza concreta di “voler tenere Laravel così com’è e scrivere il frontend in React/Vue”. La sua forza principale è la semplicità di passare dati direttamente dal controller ai componenti senza progettare un’API. Il fatto che gli starter kit di Laravel 13 supportino Inertia dimostra come la sua posizione nell’ecosistema Laravel sia ormai consolidata. Se Livewire è l’approccio per creare UI dinamiche solo con PHP, Inertia è l’approccio che permette di usare la potenza dei framework JavaScript senza rinunciare alla semplicità del lato server. Quale scegliere dipende dalle competenze del team e dai requisiti del progetto, ma quando vuoi “mantenere i controller Laravel e realizzare le schermate in React”, Inertia è la scelta più naturale.

Documentazione ufficiale di Inertia.js

Per tutte le funzionalità di Inertia v3 fai riferimento alla documentazione ufficiale.
Ultima modifica il 13 luglio 2026