Laravel and Svelte with Inertia
Tags: laravel, svelte, inertia, framework
Published: 2020-10-18 04:52:23

It started with getting to know [Svelte] (https://svelte.dev/) and her beauty, then fell in love at first sight. Ehm... But I wasn't ready if I had to bring it together with [Sapper] (https://sapper.svelte.dev/), which was meant to be.

So after searching here and there, trying all the ways that I found in the virtual universe. I met with [**Inertia**] (https://inertiajs.com/).

## What is Inertia?

Inertia allows you to create Single-page Apps (SPA) without the need to build an API. Which means you don't need to bother with complicated things like routing and API.

As far as I am concerned, all APIs and routing will still use server-side, which will be directed to the Inertia adapter. Then Inertia turns it into an XHR request and throws it to the client side.

## The wedding

Inertia can be used for almost all back end such as Rails, Symfony, Yii2. Supported front-ends are, React, Vue. And other frameworks whose adapters are developed by the community.

But this time I will only marry Laravel and Svelte off here.
 
### Server Side

1. Prepare the Laravel application, or use what you already have.

```
laravel new application
application cd
```

1. Add inertia using a composer.

```
composer require inertiajs/inertia-laravel
```

1. Set Laravel Blade to run Inertia.

`resources/views/app.blade.php`

``` html
<! DOCTYPE html>
<html>
<head>
   <meta charset = "utf-8" />
   <meta name = "viewport" content = "width = device-width, initial-scale = 1.0, maximum-scale = 1.0" />
   <link href = "{{mix ('/ css/app.css')}}" rel = "stylesheet" />
   <script src = "{{mix ('/ js/app.js')}}" defer> </script>
</head>
<body>
@inertia
</body>
</html>
```

1. Asset Versioning


`app/Providers/AppServiceProvider.php`

``` php
<?php

App\Providers namespace;

use Illuminate\Support\ServiceProvider;
use Inertia\Inertia;

the AppServiceProvider class extends ServiceProvider
{
    public function register ()
    {
        //
    }

    public boot function ()
    {
        Inertia :: version (function () {
            return md5_file (public_path ('mix-manifest.json'));
        });
    }
}
```

### Client Side

1. Add the required packages

```
npm install @inertiajs/inertia @inertiajs/inertia-svelte
npm install @babel/plugin-syntax-dynamic-import laravel-mix-svelte
```

1. Code splitting is commonly used by frameworks, you need babel for this.

create the `.babelrc` file it contains

``` json
{
  "plugins": ["@babel/plugin-syntax-dynamic-import"]
}
```

1. Initialize main JavaScript

`resources/js/app.js`

``` js
import {InertiaApp} from '@inertiajs/inertia-svelte'

const app = document.getElementById ('app')

new InertiaApp ({
  target: app,
  props: {
    initialPage: JSON.parse (app.dataset.page),
    resolveComponent: name => import (`./Pages/$ {name} .svelte`) .then (module => module.default),
  },
})
```

1. Configure script building
 
I use laravel-mix plus laravel-mix-svelte

`webpack.mix.js`

``` js
const mix = require ('laravel-mix');
require ('laravel-mix-svelte');

mix.js ('resources/js/app.js', 'public/js')
    .sass ('resources/sass/app.scss', 'public/css')
    .svelte ({
        dev:! mix.inProduction ()
    })
    .webpackConfig ({
        output: {chunkFilename: 'js/[name]. js? id = [chunkhash]'},
    })
    .version ();
```

## Use Laravel and Svelte

For the Svelte section, you can create a view with the extension `.svelte` in the` resources/js/Pages` directory according to what was set in the initialization. Such as `resources/js/Pages/Books/Show.svelte`

`resources/js/Pages/Index.svelte`

``` html
<script>
let name = 'world';
</script>

<style>
h1 {
    color: indigo;
    font-family: 'Calibri', cursive;
    font-size: 3em;
}
</style>

<h1> Svelte greets {name} through inertia </h1>
```

Then in the Laravel section, you can create a router to render its view or process data in the controller as usual. Don't forget to add `use Inertia\Inertia;` at the top of the controller

`routes/web.php`

``` php
Route :: get ('/', function () {
return Inertia\Inertia :: render ('Index');
}
```

--- edit
I forgot to mention a ready to use my repository: https://github.com/dansvel/laravel-svelte