Table of contents [Show]
- Introduction
- Understanding the Stack
- Why Use Laravel + Vue.js + Inertia Together?
- Step 1: Setting Up Laravel
- Step 2: Installing Inertia.js
- Step 3: Installing Vue.js
- Step 4: Configuring Inertia with Vue
- Step 5: Creating Your First Page
- Step 6: Passing Data from Laravel to Vue
- Step 7: Forms and Validation
- Step 8: Shared Data
- Step 9: Layouts
- Step 10: Authentication
- Example Comparison Table
- Conclusion
Introduction
Modern web application development often demands a seamless integration between backend frameworks and frontend JavaScript libraries. Traditionally, Laravel has been the go-to backend framework for PHP developers, offering robustness, simplicity, and scalability. On the other hand, Vue.js has gained popularity as a progressive frontend framework due to its simplicity and reactive components.
But how do we combine these two worlds without falling into the complexity of building a full-blown SPA with an API backend? That’s where Inertia.js comes in. Inertia acts as the “glue” between Laravel and Vue, allowing us to create full-stack applications without the overhead of managing APIs or complex frontend routing setups.
In this article, we’ll dive deep into building a modern Laravel + Vue.js + Inertia app, step by step, covering everything from setup to advanced features.
Understanding the Stack
What is Laravel?
Laravel is a PHP-based web application framework known for its elegant syntax, rich ecosystem, and developer-friendly features. It provides tools for routing, authentication, database migrations, and more, making it a full-featured backend solution.
What is Vue.js?
Vue.js is a JavaScript framework for building user interfaces. It allows developers to create reusable and reactive components, making frontend development more efficient and scalable.
What is Inertia.js?
Inertia.js is not a framework but rather a bridge that connects server-side frameworks like Laravel with frontend libraries like Vue or React. It eliminates the need for a separate API, letting you use server-side controllers and routes while rendering frontend views with Vue.
Why Use Laravel + Vue.js + Inertia Together?
Combining Laravel, Vue.js, and Inertia offers several advantages:
- Faster development by avoiding the need for APIs.
- SPA-like user experience without the SPA complexity.
- Shared state management between backend and frontend.
- Cleaner project architecture.
Step 1: Setting Up Laravel
First, let’s install Laravel. You need PHP 8+, Composer, and a database (MySQL/PostgreSQL) installed.
composer create-project laravel/laravel inertia-vue-appNavigate into the project directory:
cd inertia-vue-appSet up your environment variables in .env file:
APP_NAME="InertiaVueApp"
APP_URL=http://localhost:8000
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=inertia_app
DB_USERNAME=root
DB_PASSWORD=Run migrations:
php artisan migrateStep 2: Installing Inertia.js
We’ll use the official Laravel Inertia package. Install it using Composer:
composer require inertiajs/inertia-laravelPublish the Inertia middleware:
php artisan inertia:middlewareThis creates HandleInertiaRequests.php in the App/Http/Middleware directory. Add it to your web middleware group in Kernel.php.
Step 3: Installing Vue.js
Next, install Vue 3 along with Vite support:
npm install vue @vitejs/plugin-vueUpdate your vite.config.js:
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
laravel({
input: 'resources/js/app.js',
refresh: true,
}),
vue(),
],
});Step 4: Configuring Inertia with Vue
Update resources/js/app.js:
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/vue3';
createInertiaApp({
resolve: (name) => require(`./Pages/${name}.vue`),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.mount(el);
},
});Step 5: Creating Your First Page
Create a new Vue page at resources/js/Pages/Home.vue:
<template>
<div>
<h1>Welcome to Inertia + Vue + Laravel</h1>
<p>This is your first Inertia page.</p>
</div>
</template>
<script setup>
</script>Then, add a route in routes/web.php:
use Inertia\Inertia;
Route::get('/', function () {
return Inertia::render('Home');
});Now run your development server:
php artisan serve
npm run devOpen http://localhost:8000 to see your new app.
Step 6: Passing Data from Laravel to Vue
You can pass data from your Laravel controller directly to the Vue component:
Route::get('/dashboard', function () {
return Inertia::render('Dashboard', [
'user' => Auth::user(),
'notifications' => ['Welcome back!', 'You have 2 new messages.']
]);
});Then access this data in Dashboard.vue:
<template>
<div>
<h2>Hello, {{ user.name }}</h2>
<ul>
<li v-for="(note, i) in notifications" :key="i">{{ note }}</li>
</ul>
</div>
</template>
<script setup>
defineProps({
user: Object,
notifications: Array
});
</script>Step 7: Forms and Validation
Inertia simplifies forms with its form helper. Install it:
npm install @inertiajs/inertiaExample form in Vue (CreatePost.vue):
<template>
<form @submit.prevent="submit">
<input v-model="form.title" placeholder="Post title" />
<textarea v-model="form.body" placeholder="Post content"></textarea>
<button type="submit">Save</button>
</form>
</template>
<script setup>
import { useForm } from '@inertiajs/vue3';
const form = useForm({
title: '',
body: ''
});
function submit() {
form.post('/posts');
}
</script>Controller handling:
public function store(Request $request)
{
$request->validate([
'title' => 'required|string|max:255',
'body' => 'required'
]);
Post::create($request->only('title', 'body'));
return redirect()->route('posts.index');
}Step 8: Shared Data
Inertia allows sharing global data across all components by updating HandleInertiaRequests.php:
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user(),
],
]);
}Now auth.user is available globally in Vue components.
Step 9: Layouts
Create a layout file (Layouts/AppLayout.vue):
<template>
<div>
<header>
<nav>
<a href="/">Home</a>
<a href="/dashboard">Dashboard</a>
</nav>
</header>
<main>
<slot />
</main>
</div>
</template>Then use it inside pages:
<script setup>
import AppLayout from '../Layouts/AppLayout.vue';
defineOptions({ layout: AppLayout });
</script>Step 10: Authentication
You can use Laravel Breeze with Inertia and Vue for authentication:
composer require laravel/breeze --dev
php artisan breeze:install vue
npm install
npm run dev
php artisan migrateThis scaffolds authentication pages using Inertia + Vue.
Example Comparison Table
Here’s a table comparing traditional Laravel + API + Vue setup vs Laravel + Inertia + Vue:
| Feature | Laravel + API + Vue | Laravel + Inertia + Vue |
|---|---|---|
| Setup Complexity | High (API, CORS, JWT, etc.) | Low (Direct integration) |
| Data Passing | JSON responses | Direct props |
| Routing | Frontend + Backend routing | Only Laravel routing |
| Development Speed | Slower | Faster |
Conclusion
Laravel with Vue.js and Inertia.js is a powerful combination for building modern full-stack applications. It bridges the gap between server-side rendering and client-side SPAs, offering developers the best of both worlds. With simplified data passing, shared state management, and SPA-like experiences without the complexity, this stack allows teams to deliver production-ready applications faster.
If you’ve followed along, you should now have a functional Laravel + Vue + Inertia application, complete with routing, layouts, forms, and authentication. This foundation can be extended with advanced features like role-based permissions, API integrations, or real-time updates with Laravel Echo.





