Moving from Inertia.js to Laravel Livewire
A walkthrough for moving an existing app from from VILT to TALL.
I've been a huge Inertia.js fan and user for years, and was one of the first adopters after my buddy Jonathan Reinink released it back in 2019. Paired with Vue.js, it just makes spinning up app UIs so easy.
Livewire has been around for a long time too. Caleb Porzio released v1 around the same time and has been incrementally improving it through 3 major releases ever since.
I was on-site at Laracon Nashville when v3 was officially launched. The tech and features looked super impressive, and the crowd was pumped.
But I had never used Livewire myself, so the enthusiasm was a little lost on me.
That's about to change with this blog post.
I'm taking a new app I'm starting to build in my tried-and-true VILT (Vue/Inertia/Laravel/Tailwind) stack and I'm going to try to convert it and build it out in a TALL (Tailwind/Alpine/Laravel/Livewire) stack instead.
Like I said, I've never even touched Livewire before so this is a blind run. I'm also dividing this post into a few parts as I go through the process.
Time to get pumped ๐
Removing Inertia.js
I've already built out some of the functionality of this app, so this post is going to skip the parts about setting up a new Laravel project. In fact, I've also already got a bunch of Vue pages and Inertia controllers in place, which I'm going to need to convert over.
But, first things first... removing Inertia.
Admittedly, this feels strange and a disloyal, but I believe in my heart I'll be forgiven.
Let's go.
composer remove inertiajs/inertia-laravel
and
npm uninstall @inertiajs/vue3
And while I'm there, I might as well incur some collateral damage and remove Ziggy.
composer remove tightenco/ziggy
There, the Bandaid has been ripped off.
Updating Assets
Since my app is currently built as a Vue + Inertia.js SPA I need to perform some surgery on a few files to get it rebuilding.
Firstly, I need to remove all of the Inertia-related boilerplate from my app.js
file:
Before:
import '../css/app.css'
import './bootstrap'
import { createInertiaApp } from '@inertiajs/vue3'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'
import { createApp, h } from 'vue'
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m'
const appName = import.meta.env.VITE_APP_NAME
const appUrl = import.meta.env.VITE_APP_URL
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) =>
resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
setup({ el, App, props, plugin }) {
return createApp({ render: () => h(App, props) })
.use(plugin)
.use(ZiggyVue)
.provide('appName', appName)
.provide('appUrl', appUrl)
.mount(el)
},
progress: false,
})
After:
import '../css/app.css'
import './bootstrap'
I deleted my ssr.js
file too, and good riddance. SSR has always been the biggest pain with SPAs and maybe one of the biggest reasons I'm excited about trying Livewire.
Next I'm cleaning up my vite.config.js
file to remove any references to Vue, Ziggy, and SSR.
Adding Livewire
Now, to add in Livewire.
Heading over to the Livewire docs, I see that installing it is pretty straightforward:
composer require livewire/livewire
OK. That's done.
I'm going to skip adding the livewire.php
config file unless I discover I need it later on. I'm also going to assume the rest of the OOB settings will work for me.
It's cool that this single package provides both the Laravel services as well as the necessary "wiring" scripts for Livewire.
Views
OK, so far I've removed Inertia, added Livewire, and hacked up some of the build files for my app. Now that all of the assets have been changed I'm left with:
An app that won't build
A single Blade
app.blade.php
file that's kind of uselessA bunch of vestigial Vue files
Controller methods that are broken
This means the lion's share of the work that remains will be updating views, so let's get started with the layout files.
Layouts
I saw in the Quickstart section that a default layout could be created easily, so I'll do that:
php artisan livewire:layout
Et voila! ๐ค
Before I continue I'm going to move some of the stuff from the head of my old app.blade.php
file into this new layout file in /resources/views/components/
layouts.app
.blade.php.
And I deleted the old app.blade.php
so I didn't confuse myself later.
Testing it all out
Before I go any further with the rest of my views I need to test this out to see if I'm close. I'm going to just add a landing page with some content, and we'll see if it loads.
Since I'm OCD about folder structure I'm going a little fancier with the component generation:
php artisan make:livewire Home\\Index
๐๐๐
Ok, so, I guess I need to start the server so Tailwind can run:
npm run dev
And then I can visit my local site...
Oh ya, forgot about that. I've deleted that middleware and removed the reference from App\Http\Kernel.php
. Let's try again...
Closer.
But I just realized I never did anything with my controller, so I need to do that first.
And this is the first time I'm hitting a real paradigm shift with Livewire, because it's not that I need to change my controller, it's that I need to delete it.
Instead I'm mapping this route right to the Livewire component.
This is going to take some getting used to. But I'm OK with it.
I discover these are called full-page components and they leverage my layout file I just created. I'm also pleased to see I can still use different layouts for different components. And Caleb has gone absolutely bananas offering 3(? 4?) different ways of doing this, as I assume will be the pattern all over Livewire.
It's alive!
I update the page with some memorable content for this landmark event, try out live reload with a Tailwind change, and even use a snazzy attribute to change the page title.
I'm feeling the pump start to swell...
Realizing my Limitations
I don't want to squash any excitement but I'm realizing there's a ton of Inertia scaffolding that I get from Jetstream that I've not loaded into this app for Livewire.
So, I'm going to do the opposite of what's typically recommended and I'm going to run a Jetstream install into an existing app.
First, make sure I have the latest Jetstream installed:
composer require laravel/jetstream
Second, Install Jetstream with Livewire:
php artisan jetstream:install livewire
There's a bunch of other steps you can take when installing this, so browse the Jetstream docs to see what you need for your project.
Conclusion
OK, that's it for Part 1. I successfully have my app re-wired for Livewire and it's ready to have the rest of the components reworked.
Here's what I know is ahead of me and what I'll be tackling in the next post(s):
Rebuilding my two layouts, a "Public" layout for non-authed users and an "App" layout for the actual app
Building a dynamic dashboard that displays multiple data points at the same time
CRUD-style pages for some of the resources that users can manage
Sortable, filterable tables that contain 1000s of rows of data
It feels a little daunting right now (part of the reason why I stopped at this point) but I think if I take it a bit at a time I'm going to learn a ton.
Thanks for reading.