Creating Laravel + Vue + Inertia project
A little step-by-step guide

A senior PHP + JavaScript + MySql developer of large-scale websites & backends and entrepreneur living in Vilnius, Lithuania with my wife Monika and my parrot Johnny.
Very good at project management and communication, too.
I’m here to create stuff that is useful to other people. Let's keep in touch!
Update. Code snippets updated to use Inertia.js 1.0.
Recently, I've been learning what's new in the Laravel world, and I've got pretty excited about Laravel, Vue.js and Inertia.js combo.
Really, it combines the smoothness of single-page applications (SPA) and SEO friendliness of traditional server-rendered websites.
However, it's not trivial to set it up from scratch - you have to check the docs of all three technologies. So, I've made a little step-by-step guide for myself and made sure that it works.
Hopefully, it'll be useful for you, too.
And if you are impatient, like me, you can grab the working project template from GitHub.
OK, let's get started!
Create new Laravel project
# Create a project
cd ~/projects
laravel new ssr
cd ssr
# Serve the application on the PHP development server
# Keep it running in a separate terminal session
php artisan serve
# Test it by opening http://127.0.0.1:8000/ in the browser
Install and configure the server-side Inertia
Install the Inertia server-side package:
composer require inertiajs/inertia-laravelSetup the root template,
resources/views/app.blade.phpthat will be loaded on the first page visit:<!DOCTYPE html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> @vite('resources/js/app.js') @inertiaHead </head> <body> @inertia </body> </html>Create the Inertia middleware that will process AJAX loading of the pages:
php artisan inertia:middlewareRegister the
HandleInertiaRequestsmiddleware in yourApp\Http\Kernel, as the last item in your web middleware group:'web' => [ // ... \App\Http\Middleware\HandleInertiaRequests::class, ],Replace the home page route in the
routes/web.phpwith the code that renders a Vue template (we’ll implement theHomecomponent in a minute):Route::get('/', function () { return inertia('Home'); });Remove the
resources/views/welcome.blade.php.
Install and configure the client-side Inertia, Vue3 and Tailwind
Install the required Node packages:
npm install vue @inertiajs/vue3 npm install --dev @vitejs/plugin-vue tailwindcss autoprefixerUpdate your main JavaScript file,
resources/js/app.js, to boot your Inertia app:import './bootstrap'; import '../css/app.css'; import { createApp, h } from 'vue'; import { createInertiaApp } 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) .mount(el) }, })In
vite.config.js, configure Vite to handle Vue templates: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({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], });Add
postcss.config.cjsto enable Tailwind CSS post processing:module.exports = { plugins: { tailwindcss: {}, autoprefixer: {}, }, }Create
tailwind.config.jsto specify directories that should be handled by Tailwind CSS:module.exports = { content: [ "./resources/**/*.blade.php", "./resources/**/*.js", "./resources/**/*.vue", ], }Add Tailwind CSS styles to your main CSS file,
resources/css/app.css:@tailwind base; @tailwind components; @tailwind utilities;Create the
resources/js/Pages/Home.vuecomponent:<script setup> import { Head } from '@inertiajs/vue3'; </script> <template> <Head> <title>Hello, world!</title> </Head> <main class="fixed inset-0 grid place-items-center"> <h1 class="text-2xl">Hello, world!</h1> </main> </template>Build the JavaScript and CSS assets:
# Keep it running in a separate terminal session npm run devIf you use PHPStorm, add
jsconfig.jsonto help resolvingimport ... '@...'statements:{ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["resources/js/*"] } }, "exclude": ["node_modules", "public"] }




