Laravel Livewire: 14 Tips & Tricks

Published on by

Laravel Livewire: 14 Tips & Tricks image

Laravel Livewire is a great tool to achieve dynamic behavior on the page, without directly writing JavaScript code. And, like any tool, it has a lot of "hidden gems", both in its official docs, and practical extra tips provided by developers. I decided to compile some of them in this article. Let's get into it!

1. No render() needed

A typical render() method looks something like this:

// app/Http/Livewire/PostsShow.php
class PostsShow extends Component
{
public function render()
{
return view('livewire.posts-show');
}
}

But if your render() method is just a one-line to render the default view, you may delete that render() method from the component and it will all still work, loading the default render() from the vendor's method.

class PostsShow extends Component
{
// This empty component will still work and load the Blade file
}

2. Components in Subfolders

If you want to generate a component in a subfolder, like app/Http/Livewire/Folder/Component.php, you have two ways how to do it:

php artisan make:livewire Folder/Component

or

php artisan make:livewire folder.component

Notice that the first way is with the first letter uppercase, and the second way is lowercase. In both cases, there will be two files generated:

  • app/Http/Livewire/Folder/Component.php
  • resources/views/livewire/folder/component.blade.php

The subfolders will be created automatically if they don't exist.


3. Components in non-default Folder

If you use some external package with Livewire components, you may have your Livewire component in a different folder than the default app/Http/Livewire. Then, you may need to bind its name to the actual location.

Typically, it's done in app/Providers/AppServiceProvider.php (or in any service provider) method boot():

class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Livewire::component('shopping-cart', \Modules\Shop\Http\Livewire\Cart::class);
}
}

4. Easily Rename or Move Components

If you made a typo while generating the component with make:livewire, don't worry. You don't need to rename two files manually, there's a command for that.

For example, if you wrote php artisan make:livewire Prduct, but instead you want "Product", and also decided to put it into a subfolder, you can follow up with this command:

php artisan livewire:move Prduct Products/Show

The result will be this:

COMPONENT MOVED
 
CLASS: app/Http/Livewire/Prduct.php
=> app/Http/Livewire/Products/Show.php
VIEW: resources/views/livewire/prduct.blade.php
=> resources/views/livewire/products/show.blade.php

5. Change Default Component Templates

Livewire components are generated using the default templates, so-called "stubs". They are hidden away in the "vendor" folder of the Livewire package, but you can publish them and edit them according to your needs.

Run this command:

php artisan livewire:stubs

You will find a new folder /stubs with a few files.

Example of a stubs/livewire.stub:

<?php
 
namespace [namespace];
 
use Livewire\Component;
 
class [class] extends Component
{
public function render()
{
return view('[view]');
}
}

For example, if you want to generate the components without the render() method, just remove it from the stub file, and then each time you run php artisan make:livewire Component, it will take the template from your updated public stub.


6. Don't Create a Method Just to Set Value

If you have a click event that would set some value of some property, you may do something like this:

<button wire:click="showText">Show</button>

And then

class Show extends Component
{
public $showText = false;
 
public function showText() {
$this->showText = true;
}
}

But actually, you can assign a new value to the Livewire property directly from your Blade file, without having a separate method in the Livewire component.

Here's the code:

<button wire:click="$set('showText', true)">Show</button>

So, you call the $set and provide two parameters: your property name and the new value.


7. Step Even Further: Set True/False Value Easily

Following up on the last tip, if your property is a boolean variable with true/false values, and you want to have a show/hide button, you can do something like this:

<button wire:click="$toggle('showText')">Show/Hide</button>

Notice: I would personally avoid using Livewire for such simple toggle effects because it adds the additional request to the server.

Instead, it's better to use JavaScript for this, like Alpine.js:

<div x-data="{ open: false }">
<button @click="open = true">Expand</button>
 
<span x-show="open">
Content...
</span>
</div>

8. Three Ways to Minimize Server Requests

One of the main criticism of Livewire is the fact that it does too many requests to the server. If you have wire:model on the input field, each keystroke would potentially call the server to re-render the component. It's very convenient if you have some real-time effects, like "live search". But generally, server requests may be quite expensive, in terms of performance.

However, it's very easy to customize this behavior of wire:model.

  1. wire:model.debounce: by default, Livewire waits for 150ms after the keystroke on the input, before performing the request to the server. But you can override it: <input type="text" wire:model.debounce.1000ms="propertyName">

  2. wire:model.lazy: by default, Livewire is listening for all events on the input, and then performs the server requests. By providing a lazy directive, you tell Livewire to listen only to the change event. It means that the user may keep typing and changing the value, and the server request will be fired only when the user clicks away from that field.

  3. wire:model.defer: this will not fire the server requests on the change of the input. It will save the new value internally and will pass it to the next network request, which may come from other input fields or other button clicks.


9. Customize Validation Attributes

Livewire validation works very similarly to the Laravel validation engine, but with a few differences. In Laravel, if you want to customize the names of the attributes, you may define the attributes() method in a Form Request class.

In Livewire, the approach is different. In the component, you need to define a property called $validationAttributes and assign the array of key-value there:

class ContactForm extends Component
{
protected $validationAttributes = [
'email' => 'email address'
];
 
// ...

This is useful for common error messages, like "Field [XYZ] is required". By default, that XYZ is replaced with the field name, which may be not a human-friendly word, so it's worth replacing it for the error messages with something clearer.


10. Loading Indicators

Something that is described in the official documentation but quite rarely used, from what I've seen. If some action takes a while on the screen, it's worth showing some loading indicator, like a spinning gif, or just a text of "Loading data..."

In Livewire, it's very easy not only to implement but also to customize.

The most simple example of processing data: when the server request is made, it will show "Processing Payment..." text until the server request is finished and back with the result.

<div>
<button wire:click="checkout">Checkout</button>
 
<div wire:loading>
Processing Payment...
</div>
</div>

In practice, I like to show such loading indicators only if it takes a while. No point in re-rendering the DOM every time, in every possible case. What if we do it only if the request takes more than 500ms?

Easy:

<div wire:loading.delay.longer>...</div>

There are also possibilities to play around with CSS classes for loading states, attach them to specific actions, and more: read in the official docs.


11. Offline Indicator

Another documented but less known feature of Livewire is telling the user if their internet connection is lost. It can be beneficial if your application works with real-time data or multiple updates on the screen: you may blur some parts of the webpage and show the "offline" text.

It's as easy as this:

<div wire:offline>
You are now offline.
</div>

Also, as I mentioned, you may blur some elements, by assigning CSS classes, like this:

<div wire:offline.class="bg-red-300"></div>

12. Pagination with Bootstrap Framework

Similar to Laravel, Livewire uses pagination styling from the Tailwind framework, by default. Luckily, it's easy to override, just provide the different value to the property:

class ShowPosts extends Component
{
use WithPagination;
 
protected $paginationTheme = 'bootstrap';

You can check the available pagination designs directly in Livewire Github repository. While browsing that, I didn't find any information on whether the Bootstrap 4 or Bootstrap 5 version is used.


13. No Mount: Automatic Route-Model Binding

If you want to pass an object to the Livewire component, this is a typical way to do it, with the mount() method:

class ShowPost extends Component
{
public $post;
 
public function mount(Post $post)
{
$this->post = $post;
}
}

Then, somewhere in Blade, you have @livewire('show-post', $post).

But did you know that if you provide a type-hint to the Livewire property, that route-model binding would happen automatically?

class ShowPost extends Component
{
public Post $post;
}

That's it, no need to have the mount() method at all.


14. Delete Confirm Modal

If you have a "Delete" button and you want to call the confirm JavaScript modal before taking the action, this code wouldn't work correctly in Livewire:

<button wire:click="delete($post->id)"
onclick="return confirm('Are you sure?')">Delete</button>

There are a few possible solutions to this, probably the most elegant is to stop the Livewire event before it is even happening:

<button onclick="confirm('Are you sure?') || event.stopImmediatePropagation()"
wire:click="delete($post->id)">Delete</button>

That event.stopImmediatePropagation() will stop the Livewire method from being called, if the confirmation result is false.

You may find a few other possible solutions in this Github issue discussion.


That's it, less-known Livewire features and small tips. Hope it was useful!

PovilasKorop photo

Creator of Courses and Tutorials at Laravel Daily

Cube

Laravel Newsletter

Join 40k+ other developers and never miss out on new tips, tutorials, and more.

Laravel Forge logo

Laravel Forge

Easily create and manage your servers and deploy your Laravel applications in seconds.

Laravel Forge
Tinkerwell logo

Tinkerwell

The must-have code runner for Laravel developers. Tinker with AI, autocompletion and instant feedback on local and production environments.

Tinkerwell
No Compromises logo

No Compromises

Joel and Aaron, the two seasoned devs from the No Compromises podcast, are now available to hire for your Laravel project. ⬧ Flat rate of $7500/mo. ⬧ No lengthy sales process. ⬧ No contracts. ⬧ 100% money back guarantee.

No Compromises
Kirschbaum logo

Kirschbaum

Providing innovation and stability to ensure your web application succeeds.

Kirschbaum
Shift logo

Shift

Running an old Laravel version? Instant, automated Laravel upgrades and code modernization to keep your applications fresh.

Shift
Bacancy logo

Bacancy

Supercharge your project with a seasoned Laravel developer with 4-6 years of experience for just $2500/month. Get 160 hours of dedicated expertise & a risk-free 15-day trial. Schedule a call now!

Bacancy
Lucky Media logo

Lucky Media

Get Lucky Now - the ideal choice for Laravel Development, with over a decade of experience!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar: Laravel E-Commerce

E-Commerce for Laravel. An open-source package that brings the power of modern headless e-commerce functionality to Laravel.

Lunar: Laravel E-Commerce
LaraJobs logo

LaraJobs

The official Laravel job board

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit: Laravel SaaS Starter Kit

SaaSykit is a Multi-tenant Laravel SaaS Starter Kit that comes with all features required to run a modern SaaS. Payments, Beautiful Checkout, Admin Panel, User dashboard, Auth, Ready Components, Stats, Blog, Docs and more.

SaaSykit: Laravel SaaS Starter Kit
Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate logo

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate

Build your SaaS application in hours. Out-of-the-box multi-tenancy and seamless Stripe integration. Supports subscriptions and one-time purchases, allowing you to focus on building and creating without repetitive setup tasks.

Supercharge Your SaaS Development with FilamentFlow: The Ultimate Laravel Filament Boilerplate
Rector logo

Rector

Your partner for seamless Laravel upgrades, cutting costs, and accelerating innovation for successful companies

Rector
MongoDB logo

MongoDB

Enhance your PHP applications with the powerful integration of MongoDB and Laravel, empowering developers to build applications with ease and efficiency. Support transactional, search, analytics and mobile use cases while using the familiar Eloquent APIs. Discover how MongoDB's flexible, modern database can transform your Laravel applications.

MongoDB

The latest

View all →
Bluesky notification channel for Laravel image

Bluesky notification channel for Laravel

Read article
Sprout Multitenancy Package for Laravel image

Sprout Multitenancy Package for Laravel

Read article
Creating a CLI Application With Laravel and Docker image

Creating a CLI Application With Laravel and Docker

Read article
Laravel Herd Adds Native MongoDB Support image

Laravel Herd Adds Native MongoDB Support

Read article
How to Create Tech Videos for YouTube with Josh Cirre image

How to Create Tech Videos for YouTube with Josh Cirre

Read article
Integrate Unsplash in Your Laravel Application image

Integrate Unsplash in Your Laravel Application

Read article