This post is more than a year old. There is a chance the content is outdated.

Creating a Laravel 10 Application using Inertia JS, Svelte, and Tailwind CSS

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 @inertia
11 </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(): Response
10 {
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<?php
2 
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}

5b. Rename js config files

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!

Anthony Rappa

By Anthony Rappa

Hello! I'm a full stack developer from Long Island, New York. Working mainly with Laravel, Tailwind, Livewire, and Alpine.js (TALL Stack). I share everything I know about these tools and more, as well as any useful resources I find from the community. You can find me on GitHub and LinkedIn.