Creating a Laravel 10 Application using Inertia JS, Svelte, and Tailwind CSS
I told myself this year I would try to branch out and try new things. Inertia and Svelte were on my list but the documentation didn't get me up and running. It seemed I ran into problem after problem. I'm not sure if it was because I was trying to use the latest versions of everything or if I was just missing something. I'm going to share what I did to get it working.
What we're building:
We're going to build a fresh Laravel 10 application and install Inertia JS to serve Svelte components to our frontend that are styled with TailwindCSS.
Step 1: Install a fresh Laravel project
I use the global Laravel installer, so in the location you want your project you should run:
1laravel new inertia-svelte-tailwind
This will give you a folder called inertia-svelte-tailwind
Open that folder in your terminal and IDE of choice.
Step 2: Install Inertia JS
In your terminal run:
1composer require inertiajs/inertia-laravel
2a: Create the root view
Open resources/views
and delete welcome.blade.php
Create app.blade.php
in resources/views
with this content:
1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> 6 @vite('resources/js/app.js') 7 @inertiaHead 8 </head> 9 <body>10 @inertia11 </body>12</html>
2b: Install the Inertia Middleware
1php artisan inertia:middleware
Then add to your web
middleware stack in your app\Http\Kernel
file:
1protected $middlewareGroups = [2 'web' => [3 ...4 \App\Http\Middleware\HandleInertiaRequests::class,5 ],6 7 ...8];
2c: Install the Javascript packages
1yarn add svelte @inertiajs/svelte @sveltejs/vite-plugin-svelte
2d: Initialize the Inertia app
In your resources/js/app.js
file:
1import { createInertiaApp } from '@inertiajs/svelte' 2 3createInertiaApp({ 4 resolve: name => { 5 const pages = import.meta.glob('./Pages/**/*.svelte', { eager: true }) 6 return pages[`./Pages/${name}.svelte`] 7 }, 8 setup({ el, App, props }) { 9 new App({ target: el, props })10 },11})
2e: Modify vite.config.js
We need to tell vite to compile our svelte components.
We need to mark the laravel
plugin as default
and add the svelte
plugin.
Your vite config file should now look like this:
1import { defineConfig } from 'vite'; 2import laravel from 'laravel-vite-plugin'; 3import {svelte} from "@sveltejs/vite-plugin-svelte"; 4 5export default defineConfig({ 6 plugins: [ 7 laravel.default({ 8 input: ['resources/css/app.css', 'resources/js/app.js'], 9 refresh: true,10 }),11 svelte(),12 ],13});
3. Configure a default route and controller
This will serve the single page portion of your SPA.
Now, you can do this part inline in the routes file, but I prefer the single controller approach.
3a. Create an AppController
Create app\Http\Controllers\AppController
:
1<?php 2 3namespace App\Http\Controllers; 4 5use Inertia\Inertia; 6use Inertia\Response; 7 8class AppController { 9 public function index(): Response10 {11 return Inertia::render('Index', [12 'title' => 'Laravel 10, Inertia.js, Svelte, Tailwind CSS',13 ]);14 }15}
Here we are rendering an Index
svelte component using Inertia and passing some data. We will create this component in a minute.
3b. Add the default route
We need to register our singular route so Laravel serves the index page:
In your routes/web.php
file:
1<?php2 3use App\Http\Controllers\AppController;4use Illuminate\Support\Facades\Route;5 6Route::get('/', [AppController::class, 'index']);
Now our Index
svelte component will be served when the root page is loaded.
3c. Create the Index svelte component
By default, Inertia will look in resources/js/Pages
for svelte components.
Create resources/js/Pages/Index.svelte
:
1<script>2 export let title;3</script>4 5<div class="flex flex-col items-center text-center space-y-4">6 <h1 class="block mt-4 font-bold text-4xl">{title}</h1>7</div>
Svelte components start with a capital letter to differentiate them from HTML elements.
You can see we are expecting Inertia to provide a title
prop to the component which we set up in step 3a.
4. Install TailwindCSS
Now we want to be able to use Tailwind classes in our svelte components.
4a. Install the Tailwind javascript packages
1npm install -D tailwindcss postcss autoprefixer
4b. Initialize the Tailwind config file
1npx tailwindcss init -p
This will generate both tailwind.config.js
and postcss.config.js
.
4c. Add the Tailwind directives
Open app/resources/css/app.css
and add the following:
1@tailwind base;2@tailwind components;3@tailwind utilities;
4d. Add Tailwind to your base view
Open resources/views/app.blade.php
Replace the current vite call with the following:
1@vite(['resources/css/app.css', 'resources/js/app.js'])
4e. Tell Tailwind to look inside .svelte files
Open the tailwind.config.js
file and add the following line to the content
array:
1content: [2 ...3 "./resources/**/*.svelte",4],
If you ran yarn run build
right now you would get some errors. There are a few cleanup configuration we need to make before vite can compile svelte.
5. Configuration
5a. Update package.json
In order to use svelte, you need to add type="module"
to your package.json file. All together it should look like this:
1{ 2 "private": true, 3 "type": "module", 4 "scripts": { 5 "dev": "vite", 6 "build": "vite build" 7 }, 8 "devDependencies": { 9 "@inertiajs/svelte": "^1.0.3",10 "@sveltejs/vite-plugin-svelte": "^2.0.4",11 "autoprefixer": "^10.4.14",12 "axios": "^1.1.2",13 "laravel-vite-plugin": "^0.7.2",14 "postcss": "^8.4.22",15 "svelte": "^3.58.0",16 "tailwindcss": "^3.3.1",17 "vite": "^4.0.0"18 }19}
js
config files
5b. Rename Rename tailwind.config.js
and postcss.config.js
to tailwind.config.cjs
and postcss.config.cjs
Compile
You should now be able to run yarn run build
without errors.
If you run php artisan serve
you should be able to see your svelte component displaying its title and formatted with the Tailwind classes.
Github Project
I hope you found this article useful!