Inertia.js is a revolutionary approach to building single-page applications (SPAs) without the complexity of traditional SPAs that require a separate API. It acts as an 'adapter' between your server-side framework (like Laravel) and client-side frameworks (like Vue, React, or Svelte). Essentially, Inertia lets you build an SPA using classic server-side routing and controllers, but with client-side rendering.
Here's how it works:
1. Server-Side (Laravel): Instead of returning a full HTML page or a JSON API response, your Laravel controllers return an 'Inertia response'. This response is a JSON object that tells the client-side framework which JavaScript component to render and what data (props) to pass to it.
2. Client-Side (Vue/React/Svelte): When a user navigates, Inertia intercepts the link click. Instead of a full page reload, it makes an AJAX (XHR) request to the server. It then receives the Inertia JSON response, loads the specified client-side component, and renders it with the provided props.
Key Benefits:
* No API Layer Needed: You don't need to build a separate REST or GraphQL API. You can use your existing Laravel routes, controllers, and validation forms directly.
* Server-Side Rendering Advantages: You leverage Laravel's full power for routing, authentication, authorization, validation, and data fetching, just like a traditional monolithic application.
* Client-Side Reactivity: You still get the dynamic, reactive user experience of a modern SPA, powered by Vue, React, or Svelte.
* Simpler Development Workflow: It bridges the gap, allowing you to focus on a single codebase and development paradigm without the overhead of managing a separate frontend and backend.
`inertiajs/inertia-laravel` is the official server-side adapter package for Laravel. It provides the `Inertia::render()` method, middleware, and other utilities necessary to integrate Inertia.js seamlessly into your Laravel application.
Example Code
```php
// 1. Install Inertia.js Laravel adapter
// composer require inertiajs/inertia-laravel
// 2. Publish Inertia's root template (app.blade.php)
// php artisan inertia:middleware
// php artisan vendor:publish --tag=inertia-config
// 3. Example: app/Http/Middleware/HandleInertiaRequests.php (Generated by artisan command)
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
class HandleInertiaRequests extends Middleware
{
protected $rootView = 'app'; // This points to resources/views/app.blade.php
public function version(Request $request): ?string
{
return parent::version($request);
}
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth.user' => fn () => $request->user()
? $request->user()->only('id', 'name', 'email')
: null,
'flash' => fn () => [
'success' => $request->session()->get('success'),
'error' => $request->session()->get('error'),
],
]);
}
}
// 4. Example: routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DashboardController;
Route::get('/', function () {
return inertia('Welcome', ['name' => 'World']); // Using the global helper 'inertia'
});
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
// 5. Example: app/Http/Controllers/DashboardController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Inertia\Inertia;
class DashboardController extends Controller
{
public function index()
{
// Data to be passed as props to the client-side 'Dashboard' component
$users = ['Alice', 'Bob', 'Charlie'];
$isAdmin = auth()->user() ? auth()->user()->isAdmin() : false;
return Inertia::render('Dashboard', [
'users' => $users,
'isAdmin' => $isAdmin,
'appName' => config('app.name'),
]);
}
}
// 6. Example: resources/views/app.blade.php (Root Blade template)
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('app.name', 'Laravel') }}</title>
@vite(['resources/js/app.js', 'resources/css/app.css'])
@inertiaHead
</head>
<body class="font-sans antialiased">
@inertia
</body>
</html>
// 7. Example: resources/js/Pages/Dashboard.vue (Client-side Vue 3 component)
<script setup>
import { defineProps } from 'vue';
const props = defineProps({
users: Array,
isAdmin: Boolean,
appName: String,
});
</script>
<template>
<div>
<h1>Welcome to the {{ appName }} Dashboard!</h1>
<p v-if="isAdmin">You are an administrator.</p>
<p v-else>You are a regular user.</p>
<h2>Users:</h2>
<ul>
<li v-for="user in users" :key="user">{{ user }}</li>
</ul>
<p>This content is rendered by Vue.js, but the data comes from Laravel.</p>
<inertia-link href="/">Go to Welcome Page</inertia-link>
</div>
</template>
// 8. Example: resources/js/app.js (Main JavaScript entry point)
import './bootstrap';
import { createApp, h } from 'vue';
import { createInertiaApp, Link } from '@inertiajs/vue3';
createInertiaApp({
resolve: name => {
const pages = import.meta.glob('./Pages//*.vue', { eager: true });
return pages[`./Pages/${name}.vue`];
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.component('InertiaLink', Link) // Register <inertia-link> globally
.mount(el);
},
progress: {
color: '#4B5563',
},
});
```








Inertia.js with Laravel