Livewire brings reactive components to Laravel Blade. You write PHP classes and Blade templates while Livewire handles AJAX updates, validation, and DOM diffing—ideal for dashboards, wizards, and admin panels.
Installing Livewire
Install Livewire via Composer and include scripts in your layout. No separate build step is required for basic components.
Livewire 3 uses @livewireStyles and @livewireScripts directives or the @vite integration in modern Laravel apps.
Step 1: Require the Livewire package
Run composer require livewire/livewire. Publish config optionally with php artisan livewire:publish –config.
Verify installation by checking vendor/livewire/livewire and the Livewire service provider auto-discovery.
composer require livewire/livewire
Step 2: Add directives to the layout
In resources/views/layouts/app.blade.php add @livewireStyles in head and @livewireScripts before </body>.
For Livewire 3 with Volt and full-page components, use @livewire('component-name') in routes.
@livewireStyles
<!-- content -->
@livewireScripts
Step 3: Create your first component
Run php artisan make:livewire Counter. This creates app/Livewire/Counter.php and resources/views/livewire/counter.blade.php.
Embed with <livewire:counter /> or @livewire('counter') in any Blade view.
php artisan make:livewire Counter
Step 4: Render on a route
Return a view containing the component from a route or use Route::get('/counter', Counter::class) for full-page components.
Full-page routing keeps URLs clean for admin tools built entirely in Livewire.
Route::get('/counter', Counter::class);
Properties, Actions, and Forms
Public properties on Livewire components are reactive. wire:model binds inputs to properties with automatic server sync.
Call public methods from the template with wire:click. Validation uses the same rules as HTTP controllers.
Step 1: Define reactive properties
In Counter.php set public int $count = 0. Increment with a public function increment() { $this->count++; }.
Bind the button: <button wire:click="increment">+</button>. Livewire re-renders only the changed DOM nodes.
public int $count = 0;
public function increment(): void
{
$this->count++;
}
Step 2: Bind forms with wire:model
Use wire:model="email" on inputs. Add wire:model.live for instant updates or .blur for on-blur sync.
Large forms benefit from wire:model.defer to batch updates on submit instead of every keystroke.
<input type="text" wire:model="email">
Step 3: Validate inside the component
Call $this->validate(['email' => 'required|email']) in save() or use rules() method returning validation rules.
Display errors with @error('email') like standard Blade forms. Validation runs server-side on every action.
protected function rules(): array
{
return ['email' => 'required|email'];
}
Step 4: Flash messages and redirects
Use session()->flash('status', 'Saved!') then render in the template. Redirect with return $this->redirect('/posts').
return $this->redirectRoute('posts.index') after create forms for PRG pattern compliance.
$this->redirectRoute('posts.index');
Advanced Livewire Patterns
Pagination, file uploads, and nested components scale Livewire to complex interfaces.
Use wire:loading directives for UX feedback while server actions run.
Step 1: Paginate Eloquent results
Use WithPagination trait and paginate() in render(): Post::paginate(10). Links work with wire:click preserved.
Theme pagination views to match your design. Livewire handles query string state automatically.
use LivewireWithPagination;
public function render()
{
return view('livewire.post-list', [
'posts' => Post::paginate(10),
]);
}
Step 2: Upload files with WithFileUploads
Add use WithFileUploads and public $photo. Validate and store in save() using $this->photo->store('photos', 'public').
Show progress with wire:loading on the submit button. Temporary preview uses $this->photo->temporaryUrl().
use LivewireWithFileUploads;
public $photo;
Step 3: Emit events between components
Dispatch events with $this->dispatch('post-created') and listen via #[On('post-created')] attribute on other components.
Event bus decouples modals, notifications, and list refresh logic across the page.
$this->dispatch('post-created');
Step 4: Test Livewire components
Use Livewire::test(Counter::class)->set('count', 5)->call('increment')->assertSet('count', 6).
Feature tests exercise real HTTP while Livewire::test isolates component logic quickly.
Livewire::test(Counter::class)
->call('increment')
->assertSet('count', 1);
Aadyanex builds production-ready Laravel applications with clean architecture, secure APIs, and long-term support.
