Inertia bridges Laravel backends and modern JavaScript frontends. You write controllers that return Inertia responses instead of JSON APIs, while Vue or React renders pages with client-side navigation.
Installing Inertia with Breeze
Laravel Breeze offers Inertia stacks for Vue and React with authentication scaffolding.
The server adapter inertiajs/inertia-laravel pairs with @inertiajs/vue3 or @inertiajs/react on the frontend.
Step 1: Create a fresh Laravel app with Breeze
Run composer require laravel/breeze –dev then php artisan breeze:install vue or react –inertia.
npm install && npm run dev compiles assets. php artisan migrate sets up auth tables.
composer require laravel/breeze --dev
php artisan breeze:install vue --inertia
npm install && npm run dev
Step 2: Understand the Inertia response
Controllers return Inertia::render('Dashboard', ['stats' => $stats]) instead of view() or json().
Props serialize to JSON embedded in the page. Subsequent visits use XHR with partial data loads.
return Inertia::render('Dashboard', [
'stats' => $stats,
]);
Step 3: Configure the root Blade template
resources/views/app.blade.php includes @vite directives and @inertia directive where the SPA mounts.
The @inertiaHead slot manages meta tags for SEO on JavaScript-driven pages.
@vite(['resources/js/app.js'])
@inertia
Step 4: Define routes as usual
routes/web.php stays in Laravel. Middleware, policies, and sessions work identically to Blade apps.
Only the response format changes. Authorization still runs server-side before props are shared.
Route::get('/dashboard', [DashboardController::class, 'index'])->middleware('auth');
Vue and React Page Components
Pages live in resources/js/Pages/. File-based naming maps Dashboard.vue to Inertia::render('Dashboard').
Layouts wrap pages with navigation and flash message slots.
Step 1: Create a page component
Add resources/js/Pages/Posts/Index.vue with <script setup> and defineProps({ posts: Array }).
Link between pages using <Link href="/posts/create"> from @inertiajs/vue3 without full reloads.
<script setup>
defineProps({ posts: Array });
</script>
Step 2: Share global data with HandleInertiaRequests
In app/Http/Middleware/HandleInertiaRequests.php add auth user and flash to shared() array.
Shared props appear on every page without passing them from each controller.
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth' => ['user' => $request->user()],
]);
}
Step 3: Handle forms with useForm
Import useForm from @inertiajs/vue3. Bind fields and call form.post('/posts') for validation errors inline.
useForm tracks processing state for disabling submit buttons during requests.
const form = useForm({ title: '', body: '' });
form.post('/posts');
Step 4: Lazy load heavy props
Use optional closure props: Inertia::render('Report', ['data' => fn () => HeavyQuery::run()]).
Lazy props defer expensive queries until the client requests them, speeding initial page load.
Inertia::render('Report', [
'data' => fn () => ReportService::build(),
]);
Deployment and SSR
Production builds run npm run build. Configure SSR optionally for faster first paint and SEO.
Asset versioning through Vite manifest prevents stale JavaScript after deploys.
Step 1: Build assets for production
Run npm run build to compile hashed assets into public/build. Vite manifest maps entry points.
Set APP_ENV=production and ensure @vite loads compiled assets, not the dev server.
npm run build
Step 2: Enable Inertia SSR optionally
Run php artisan inertia:start-ssr after configuring ssr bundle in vite.config.js.
SSR renders initial HTML on the server. Subsequent navigation remains client-driven.
php artisan inertia:start-ssr
Step 3: Version assets with mix manifest
Inertia middleware shares version from parent::version() busting client cache on deploy.
Bump version when only PHP changes if props schema changes require fresh JS.
php artisan config:cache
Step 4: Organize Ziggy routes for frontend
Install tightenco/ziggy to expose named Laravel routes to JavaScript route() helper.
Frontend links stay in sync when Laravel route names change.
composer require tightenco/ziggy
php artisan ziggy:generate
Aadyanex builds production-ready Laravel applications with clean architecture, secure APIs, and long-term support.
