Livewire is a Laravel package to make powerful, dynamic, front-end UI. It offers a convenient way of building SPA-like interactive apps with PHP (without writing JavaScript).
On July 20th of 2023, at Laracon US, the new shiny Laravel Livewire v3 is officially released. With the new Alpine based core and a bunch of new features – it’s going to be awesome!
Let’s explore the fresh, out-of-the-oven Livewire. ♨️
We are going to build a Fortune Cookie Message app. These are small, inspirational, positive messages printed on paper and served inside specially shaped cookies. See the story here.
We’ll make it in a 3 step journey with the following milestones:
- Make a new Livewire app. Show up a different inspirational message every time we hit a button.
- Add an Emoji reaction counter. Explore various livewire features.
- Make an admin section with authentication and a data grid.
It’s small enough to try and complete within a day but has the scope of exploring various interactivity features.
Prerequisites
As Livewire is a package for Laravel, you should have a basic understanding of Laravel to start this journey. Also, Livewire v3 requires Laravel 9 or later and PHP 8.1 or later.
Experience in Livewire V2 is NOT required.
Starting a Livewire v3 project
To start a Livewire project, we actually need to set up a new laravel 10 project and install the Livewire package later. Let’s start.
First, start a fresh Laravel project using your preferred installation method. Then add the Livewire using composer.
composer require livewire/livewire
Check the latest stable release here.
Making a Livewire component
Components in Livewire applications serve as the building blocks for creating reusable UI elements by combining state and behavior. In this guide, we will explore the essential steps of creating and rendering components.
Now we are ready to make our hands dirty with Livewire. Let’s make out the first ever Livewire v3 component, the Cookie.
php artisan make:livewire cookie
If the command was successful, you’d see the following filenames along with the congratulatory message in the console output.
CLASS: app/Livewire/Cookie.php
VIEW: resources/views/livewire/cookie.blade.php
So, these files are created by the command to program our Cookie livewire component. Let’s see how we can use them to show us a fortune message.
Open the app/Livewire/Cookie.php
class. It’s just rendering the view file of the component.
<?php
namespace App\Livewire;
use Livewire\Component;
class Cookie extends Component
{
public function render()
{
return view('livewire.cookie');
}
}
We’ll start with the simplest possible way. And will make progress in baby steps.
Let’s add a list of fortune messages to this component class. Also, we need a button to randomly show a different message from our list (not even from a database, yet).
<?php
namespace App\Livewire;
use Livewire\Component;
class Cookie extends Component
{
private array $messages = [
'Time may fly by. But Memories don\'t.',
'Nothing in the world is accomplished without passion.',
'The project on your mind will soon gain momentum.',
'A dream you have will come true.',
'A journey of a thousand miles begins with a single step.',
];
// Message to display to the visitor
public string $message;
public function rotate()
{
$this->message = Arr::random($this->messages);
}
public function mount()
{
$this->rotate();
}
public function render()
{
return view('livewire.cookie');
}
}
In a livewire component, the public properties are made available to the component’s Blade view automatically. And they can be used using standard Blade syntax. Also, the public functions are the actions that can be triggered from the front end. We have a rotate()
action here that will pick a random message to display when performed.
Also, we’ve added a mount()
method. It works as the entry point for a Component. So it’ll be called at the beginning of rendering the view and will set the initial message.
Let’s display the public attribute $message
as so-called Fortune Message and bind the action rorate()
in the component view file resources/views/livewire/cookie.blade.php
.
<div>
<h1>{{ $message }}</h1>
<button wire:click="rotate">
Surprise Me!
</button>
</div>
Using wire:click
, we are binding the action with the click event of the button. Here is the magic of Livewire. When we will click the button on the front end (browser), it will trigger the action in the backend (server). Also, if it makes any change to any component property, ($message
in our case) the view will be automatically re-rendered to reflect the change.
Displaying the Livewire Component
A Livewire component can be rendered in 2 ways.
- Include in a regular blade view using
<livewire:component-name />
tag - Assign to a route directly as a full-page component
We’ll use the second option here. And, let’s plan to explore the first option in the third part – the admin panel.
So, let’s add the following route in routes/web.php
file, after the homepage route. The Livewire Component class should be mentioned in place of the controller.
Route::get('/fortune', \App\Livewire\Cookie::class);
Also we’ll need a layout to render the component in. The following command will make it for us.
php artisan livewire:layout
It’ll make the boilerplate layout at resources/views/components/layouts/app.blade.php
. You’ll see a {{ $slot }}
placeholder in the layout. This is the point where the output of our component will be displayed.
Let’s go to the browser and hit to http://localhost:<port-number>/fortune
. There is a good news waiting for us!
Every time we click the “Surprise Me!” button, it’ll show us a piece of inspiration!
Before moving forward, let’s give our shiny new app a funny facelift. To keep things simple and focused, I am not adding any css framework here. Just a CSS section in the header and a couple of inline CSS, that’s it. Here are the changes.
It’s nice to see that – we have successfully created a tiny Livewire V3 App!
🎊🎉🎊🎊🎉🎊🎊🎉
Now, if we keep clicking on the button, it’ll show us a nice message every time. But, sometimes, it’s showing the same message! Because picking a random item from a small set have a high chance of getting a duplicate result.
Before closing this part, let’s improve the random message selection. Instead of Arr::random()
, we can use PHP array_rand()
function to pick a random index from $messages
array in our rotate()
function. Also, we need a new property to keep track of the current index of the $messages
array. Then, if we get the same index in rotation, we’ll just rotate again.
Let’s add the following property in the Component class.
use Livewire\Features\SupportLockedProperties\Locked;
class Cookie extends Component
{
// ...
#[Locked]
public int $currentIndex = 0;
// ...
}
We have added $currentIndex
property to keep track of the current message. We don’t want this property to remain changeable from the browser. So we’ve annotated this property with #[Locked]
attribute to prevent modification from the front end.
Then, update the logic in rotate()
action.
class Cookie extends Component
{
// ...
public function rotate()
{
$key = array_rand($this->messages);
if ($key !== $this->currentIndex) {
$this->currentIndex = $key;
$this->message = $this->messages[$key];
} else {
$this->rotate();
}
}
// ...
Done. We should not see the same message on the next click.
Source Code
Here is the repository for the sample app. You’ll get the source code for this part here. It also includes tests for what we have built so far.
Suggestions, fixes, and improvements are very much welcome! 🤗
Conclusion
We have already used a few new features of Livewire V3. i.e.,
- Livewire scripts, styles, and Alpine were injected automatically, we didn’t do anything in our layout or view. We didn’t manually add
@livewireStyles
,@livewireScripts
, Alpine etc. /** @locked */
properties to prevent unwanted modification.
In the next part, we’ll fetch data from the database instead of a static array. Also, we’ll add an emoji reaction counter so that the user can express his feelings after seeing a message. In the process of doing that, we’ll focus on exploring a couple of Livewire V3 features. e.g.,
- Teleport
- Reactive properties
- Accessing the parent component’s data
- Small JS functions within the component
- Navigating with prefetch
Hope we’ll enjoy exploring Livewire V3 together! Stay tuned. 👋
If you find this article useful, you may follow me on Twitter (@ajaxray) and subscribe to my newsletter {BetweenCurlyBrackets} for future content on Laravel, PHP, and Web Application development.
Thank you! 🤗