In this first lesson, I want to demonstrate Livewire in action, explaining the installation and syntax along the way.
Text Version of the Lesson
Imagine you have a form with country/city dropdown fields:

You want the form to be dynamic, so whenever a country is chosen, the city list will auto-reload with cities from that specific country.

Notice: I intentionally left out any CSS or design so we could focus on the functionality.
A typical way to do it would be with JavaScript and frameworks like Vue or React.
But Livewire allows you to achieve it without writing any line of JavaScript.
Let me show you.
If you want to follow along with the repository, the link to GitHub will be at the end of this lesson.
Code BEFORE Livewire
So, this is the initial code of Controller + Blade, without Livewire:
app/Http/Controllers/CompanyController.php:
namespace App\Http\Controllers; use App\Models\Country; class CompanyController extends Controller{ public function create() { $countries = Country::all(); return view('companies.create', compact('countries')); }}
resources/views/companies/create.blade.php:
<html><body><form> <label for="name">Company name</label> <br /> <input name="name" required /> <br /><br /> <label for="country_id">Country</label> <br /> <select name="country_id" required> <option value="">-- choose country --</option> @foreach ($countries as $country) <option value="{{ $country->id }}">{{ $country->name }}</option> @endforeach </select> <br /><br /> <label for="city_id">City</label> <br /> <select name="city_id"> <option value="">-- choose country first --</option> </select> <br /><br /> <button type="submit">Save data</button></form> </body></html>
Now, look at the code of dynamic dependent dropdowns with Livewire below.
Code WITH Livewire
First, we install Livewire. It's just one Composer command:
composer require livewire/livewire
Then, we turn our form into a Livewire component that would be included in the regular Blade.
php artisan make:livewire CompanyCreate
It will generate two files:
- Livewire Component class: app/Livewire/CompanyCreate.php
- Livewire Blade file: resources/views/livewire/company-create.blade.php
Then, the main Laravel Blade turns into this, just loading the Livewire component...
slightly off topic but I've found MingleJS which appears to let you use React or Vue in a Livewire app.. will test it out this weekend and report back
thank you
Hi, Livewire looks really promising!
I have a few questions:
What kind of impact does using Livewire have on SEO?
From an SEO perspective, is it better to use Blade pages with Livewire components and regular routing, or use full-page components instead?
And if using regular Blade routes, how does SEO behave when using wire:navigate for navigation between pages?
How does Livewire 3 compare to Inertia 2 in terms of SEO?
PS. I noticed you have a lesson about SEO in the SPLADE course — maybe something similar for Livewire and Inertia would be super helpful? Also, a dedicated SEO-focused component in LivewireKit could be a great idea! This topic feels important enough to deserve a deeper analysis, maybe even a full article, premium tutorial, or course ;)
Best regards, Tom
Sorry for a late reply:
For SEO it is better to use Blade pages with Livewire components. That way, it renders the pages via HTML and not JS, which is often an issue with SEO. And this is true for Inertia too - it's a SPA application, so page loads via JS, rather than HTML.
As for the blade routes - you then use the links, instead of
wire:navigatesince you want the page to fully refresh.In general, the SEO topic is complex and can't take anything for granted. I've seen SPA pages being indexed correctly multiple times, so my comment can be wrong too. In general, it's important to add all the required tags, information for the page. Other than that - SEO can change within a few weeks of project launch, so it's a constant battle.
Great lesson as always! Thank you.
Isn't it $country instead of $country_id here in this line?
"Also, that wire:model means binding to the component property $country_id."
Thank you for noting! Fixed the typo there