Moving from Inertia.js to Laravel Livewire

Adam CampbellAdam Campbell
6 min read

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.

โ„น
All of this cleaning up has also resulted in me removing a ton of additional Vue-related packages that are no longer needed. If you're going through this process be sure to do the same.

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 useless

  • A 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.

โ—
Disclaimer: I ended up having to spin up a temporary new Laravel project with Livewire-flavored Jetstream so I could copy a bunch of views in my project. Stuff was broken, and this was easier.

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.

0
Subscribe to my newsletter

Read articles from Adam Campbell directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Adam Campbell
Adam Campbell