Laravel Tutorials

Real-time Form Updates with Laravel Livewire's wire:model.live

Published Updated
Real-time Form Updates with Laravel Livewire's wire:model.live image

Laravel Livewire v3 changed how wire:model works, making it one of the few breaking changes from v2. In Livewire v2, wire:model was "live" by default, sending a request to the server after every keystroke. This caused performance issues with too many server requests, especially on text inputs.

In v3, the team made wire:model deferred by default. This means the client-side gets updated on every change, but the server-side gets queued until an action is performed (like clicking a submit button). If you want the old v2 behavior where changes sync immediately as users type, you need wire:model.live.

<input type="text" wire:model.live="searchQuery">

The key difference: wire:model waits for an action, wire:model.live syncs on every keystroke. This matters for things like search boxes where you want results to update as users type.

When you use wire:model.live, Livewire automatically adds a 150ms debounce. This means if a user keeps typing, Livewire waits until they stop typing for 150ms before sending the request. This prevents your server from being hammered with requests. You can customize the debounce timing:

<input type="text" wire:model.live.debounce.300ms="userInput">

There's also a .throttle modifier if you want different behavior. While .debounce waits until the user stops typing, .throttle sends requests at regular intervals while the user is still typing. For most cases, debounce is what you want.

Here's a search component that filters a book collection:

<div>
<input type="text"
wire:model.live.debounce.250ms="query"
placeholder="Search books...">
 
@if($query && strlen($query) >= 2)
<div class="results">
@foreach($books as $book)
<div class="book-item">
<strong>{{ $book->title }}</strong> by {{ $book->author }}
<span class="year">({{ $book->year }})</span>
</div>
@endforeach
 
@if($books->isEmpty())
<p>No books found for "{{ $query }}"</p>
@endif
</div>
@endif
</div>

The component waits until users type at least 2 characters before searching. This is a common pattern to avoid unnecessary database queries on single characters.

class BookSearch extends Component
{
public $query = '';
public $books = [];
 
public function updatedQuery()
{
if (strlen($this->query) >= 2) {
$this->books = Book::where('title', 'like', '%' . $this->query . '%')
->orWhere('author', 'like', '%' . $this->query . '%')
->take(15)
->get();
} else {
$this->books = collect();
}
}
 
public function render()
{
return view('livewire.book-search');
}
}

The updatedQuery() method runs whenever the query property changes. This happens because of wire:model.live. Without the .live modifier, this method wouldn't fire until the next form submission or manual action. You can also use other modifiers like wire:model.blur to only update when the user tabs out of the field, or wire:model.change for dropdowns.

Harris Raftopoulos photo

Senior Software Engineer • Staff & Educator @ Laravel News • Co-organizer @ Laravel Greece Meetup

Sponsored

laravelcloud logo
Laravel Cloud

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

Visit Laravel Cloud

The latest

View all →
Fluent Rule Builders for All Laravel Validation Rules image

Fluent Rule Builders for All Laravel Validation Rules

Read article
Laravel URL AI Transformer: Extract Structured Data From URLs image

Laravel URL AI Transformer: Extract Structured Data From URLs

Read article
Rule Builders for Every Validation Rule in Laravel 13.36 image

Rule Builders for Every Validation Rule in Laravel 13.36

Read article
PHP News: A New Site for PHP Releases, RFCs, and Packages image

PHP News: A New Site for PHP Releases, RFCs, and Packages

Read article
Pause Polling in Background Tabs in Inertia.js v3.9 image

Pause Polling in Background Tabs in Inertia.js v3.9

Read article
Look What You Helped Me Build image

Look What You Helped Me Build

Read article