If you’ve been coding with Laravel for some time, you must have heard about the ‘magical’ Laravel Livewire package. Livewire is a truly awesome (and almost magic) way to create interactive interfaces and communicate ‘realtime’ with your Laravel backend. And it does this all in a very simple way. In this article I’ll show you the basics of Laravel Livewire, so that you will be up-and-running with Livewire in no-time🚀
The combination of simplicity and power is what makes Laravel Livewire so awesome and why it is used by so many developers. It is especially a good alternative to the Laravel + Inertia + Vue combination, in particular if you’re still used to the ‘Vue-magic’, but feel that Vue is too much of a hassle to set up.
The basics of Livewire
The first thing you should know is that Livewire works with so-called components. That means that you can have a search component, an edit component, you name it. Each Livewire component consists of (in most cases) two files:
- The component class file
- The Blade file with the markup (the HTML)
Additionally, you could also have a test for each component, but that’s something you should care about later (but don’t forget it!😄).
Installing Livewire
First, you need to install Laravel Livewire. To do so, run the following composer command:
composer require livewire/livewire
Next, you need to load a Livewire JavaScript file and a Livewire CSS file. Without loading those files on a page, you cannot use Livewire. Luckily, Livewire makes this really easy for us. All you need to do is adding the below two Blade directives in your Blade files and make sure that these directives are loaded on every page.
The best place to put them is normally in your layouts/app.blade.php
file:
<html>
<head>
...
@livewireStyles
</head>
<body>
...
@livewireScripts
</body>
</html>
Creating Livewire components
Now it’s time to create our first Livewire component! The best way to create a Livewire component is to run the following artisan command, similar to the regular Laravel artisan commands:
php artisan make:livewire ComponentName
This will create two files, the file with the Livewire logic and the Blade layout:
- App\Http\Livewire\ComponentName.php
- resources/views/livewire/component-name.blade.php
You can also create a Livewire component in a namespace:
php artisan make:livewire Dashboard/ComponentName
The above command creates the following two files:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ComponentName extends Component
{
public function render()
{
return view('livewire.component-name');
}
}
<div>
</div>
With just these two files you can create great interactive Livewire components!
Creating a Livewire search component
So, what’s so special about Livewire? The special ‘magic’ thing about Livewire is that it allows (almost) realtime communication between your server (the backend) and the frontend. This means that you could have a variable, change it in your PHP and the frontend automatically updates with the new values.
Imagine that you have a page in your Laravel app with tabs. You could have a variable that holds the name of the current tab. In your frontend Blade files, you could do an @if()
condition to show the correct markup. Changing the variable for example on click, the markup would automatically change without reloading the page!🤯
The Livewire website has a great example on their homepage that shows the power of Livewire, so let’s start with that.
use Livewire\Component;
class SearchUsers extends Component
{
public $search = '';
public function render()
{
return view('livewire.search-users', [
'users' => User::where('username', $this->search)->get(),
]);
}
}
<div>
<input wire:model="search" type="text" placeholder="Search users..."/>
<ul>
@foreach($users as $user)
<li></li>
@endforeach
</ul>
</div>
So, what do we see here? We see that we have a variable in our Livewire component, called $search
. Every variable (or property or attribute) that you declare as public
on the Livewire class, is available to the frontend and it updates realtime.
The frontend has an <input>
element where people enter their search query. The value of this input element is ‘connected’ to the value of the public $search
property. And the $users
variable that is passed to the frontend, depends on the public $search
. So if the value of public $search
changes, the value of $users
changes and the frontend also updates – without a page reload. Magic, right?
How to display a Livewire component
Now that you’ve got an idea of how a Livewire component looks like, you might be wondering how to display it on a page. There are multiple ways to display a component, so you can choose one of the following ways to include a Livewire component in a Blade file:
<livewire:search-users />
@livewire('search-users')
@livewire(App\Http\Livewire\SearchUsers::class)
You can also add data to each Livewire component:
@livewire('search-users', [ 'company' => $company ])
// Add the following public property to your SearchUsers component. Livewire will map the $company automatically to the correct property.
public Company $company;
// If you want more control over how the properties are stored, you can also accept them in the mount() method:
public Company $myCompany;
public function mount(Company $company) {
$this->myCompany = $company;
}
You can also use Livewire as a full-page component. That means that this would work:
use App\Http\Livewire\SearchUsers;
Route::get('/{organization}/users/search', SearchUsers::class);
public function render()
{
return view('livewire.search-users', [
'users' => User::where('username', $this->search)->get(),
])->extends('layouts.app');
}
Checkout the Livewire docs for more information if you’re interested in using fullpage components.
Using Actions
Another very handy thing is the use of Livewire actions. Livewire actions mean you can define a public function on your component and call this action from the frontend. For example, if a user clicks on a button.
This example comes from the docs and I think that it’s a great example that shows the power of Livewire really well:
class ShowPost extends Component
{
public Post $post;
public function like()
{
$this->post->addLikeBy(auth()->user());
}
}
<div>
<button wire:click="like">Like Post</button>
</div>
As a summary, Livewire will now call the like()
function every time the users click the <button>
. You can add a wire:click=""
directive to every element you want, so it is not limited to buttons and <a href="">
s.
Using forms with Laravel Livewire
Next, I would like to talk about forms in Livewire. The way Livewire handles forms might classify as one of the most powerful Livewire features. It wouldn’t surprise me if it is one of the most commonly used features.
Let’s see how it works.
First, we have the Blade file. Just like in ‘regular’ non-Livewire HTML, each form is wrapped in a <form>
tag. The big difference is that a Livewire form doesn’t have the action=""
, type=""
and method=""
tags.
So how do we tell Livewire where to send the information to?
We can do so with the wire:submit.prevent
attribute. Adding this attribute to the <form>
looks like this: <form wire:submit.prevent="save">
. It tells Livewire: ‘when the form is submitted, prevent the normal submit action and call the save()
function instead.
Let’s see this in action. We start by modifying our Blade file so that it contains a very simple form, asking for just an e-mailaddress.
<div>
<form wire:submit.prevent="save">
<input type="email" wire:model="email" placeholder="Email">
<button type="submit">Submit form</button>
</form>
</div>
Next, let’s add the function save()
to the Livewire component:
public function save()
{
$this->validate();
$user = User::create([
'email' => $this->email,
]);
dump('User created successfully!');
}
Let’s also add a public property called $email
and make sure to set a default value like an empty string, ''
. If the field is optional, you can also make the variable type nullable by adding a ?
before the type and assigning a default value of null
.
public string $email = '';
public ?string $email = null; // Optional field
This property will always contain the value of the input field, because we bind these values together with the wire:model="email"
attribute on the input.
You see that we’re using the $this->validate()
method. This should always be the first method in your save()
function, because it will run all the validation rules. If the validation fails, it stops the flow of the code.
So how do we define those rules?
To do so, add a protected $rules
property to the Livewire component. (See the power of favouring convention over configuration?)
protected $rules [
'email' => 'required|email'
];
Now, we are almost ready to start using our first Livewire component. We only need a place to display potential error messages.
You can use the @error
directive for that. Now our Blade file should look like this:
<div>
<form wire:submit.prevent="save">
<input type="email" wire:model="email" placeholder="Email">
@error('email') <span class="error"></span> @enderror
<button type="submit">Submit form</button>
</form>
</div>
If you want to customize the error messages or the attribute names, checkout the documentation.
Realtime form validation & Livewire lifecycle hooks
Another cool feature I want to show you, is the realtime validation feature. How is that possible?
Livewire allows you to add specific function to the component, like updatedVARIABLENAME()
, updatingVARIABLENAME()
. Those functions are called lifecycle hooks. You can add them for each variable, and each time that variable is updated, this function will run.
So if we want to validate the $email
input every it changes – realtime as the user is typing – we can use a lifecycle hook for that:
public function updatedEmail($value)
{
$this->validateOnly('email');
}
You can also use a more generic lifecycle hook, which runs on every property update. This is in particular handy if you have long forms and you don’t want ten functions all doing the same validation over and over.
public function updated($propertyName)
{
$this->validateOnly($propertyName);
}
Next steps
As you’ve seen, Livewire allows PHP-developers to implement pretty amazing interactivity in their Laravel-apps, without developers needing to write a single line of JavaScript.
For developers like me, who have much more feeling with PHP then with JavaScript, Livewire saves so much time.
Now that you know the basics of Livewire, I’d recommend to start using it as much as possible, in order to experience the full power of Livewire. There’s so much more I didn’t tell here, so start using it, take a dive in the documentation later and enjoy!⚡️
Laravel News Links