laravel-livewire
Auto-invoked skill
Create Livewire 3 components with forms, tables, modals
Trigger Keywords
This skill automatically activates when Claude detects these keywords:
livewire
wire:model
reactive
component
alpine
Overview
The laravel-livewire skill provides expertise for building reactive components with Livewire 3. It covers component lifecycle, forms, validation, real-time updates, and Alpine.js integration.
What This Skill Provides
- Component Patterns - Forms, tables, modals, wizards
- Two-way Binding - wire:model, wire:model.live, wire:model.blur
- Actions - wire:click, wire:submit, events
- Lifecycle Hooks - mount, hydrate, updated, etc.
- File Uploads - WithFileUploads trait
- Pagination - WithPagination trait
Example Conversations
# Building a form
"Create a Livewire form for user registration with real-time validation"
# Data tables
"Build a searchable, sortable data table with pagination"
# Modals
"How do I create a confirmation modal in Livewire 3?"
# Events
"Communicate between two Livewire components"
Livewire 3 Component Example
<?php
namespace App\Livewire;
use App\Models\Post;
use Livewire\Attributes\Rule;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Title('Create Post')]
class CreatePost extends Component
{
#[Rule('required|min:3')]
public string $title = '';
#[Rule('required|min:10')]
public string $content = '';
public function save()
{
$validated = $this->validate();
Post::create($validated);
session()->flash('success', 'Post created!');
$this->redirect(route('posts.index'));
}
public function render()
{
return view('livewire.create-post');
}
}
Blade Template
<form wire:submit="save">
<div>
<input wire:model.blur="title" type="text">
@error('title')
<span class="error"></span>
@enderror
</div>
<div>
<textarea wire:model.blur="content"></textarea>
@error('content')
<span class="error"></span>
@enderror
</div>
<button type="submit">
<span wire:loading.remove>Save</span>
<span wire:loading>Saving...</span>
</button>
</form>
Wire:model Modifiers
| Modifier | Behavior |
|---|---|
wire:model |
Deferred (on form submit) |
wire:model.live |
Updates on every keystroke |
wire:model.blur |
Updates when field loses focus |
wire:model.live.debounce.500ms |
Debounced live updates |
Events Between Components
// Dispatching an event
$this->dispatch('post-created', id: $post->id);
// Listening in another component
#[On('post-created')]
public function handlePostCreated(int $id): void
{
$this->posts = Post::latest()->get();
}
// From JavaScript
Livewire.dispatch('post-created', { id: 1 })
Common Pitfalls
// 1. Missing wire:key - Always use in loops
@foreach($items as $item)
<div wire:key="item-">...</div>
@endforeach
// 2. N+1 Queries in render() - Eager load relationships
// BAD
public function render()
{
return view('livewire.posts', [
'posts' => Post::all(), // N+1 when accessing $post->author
]);
}
// GOOD
public function render()
{
return view('livewire.posts', [
'posts' => Post::with('author')->get(),
]);
}
// 3. Large Component State - Store IDs, not collections
// BAD
public Collection $products;
// GOOD
public array $productIds = [];
// 4. Not Debouncing Search - Causes excessive requests
// BAD
<input wire:model.live="search">
// GOOD
<input wire:model.live.debounce.300ms="search">
// 5. Forgetting to Reset Pagination
public function updatedSearch(): void
{
$this->resetPage();
}
// 6. Memory Leaks with File Uploads
public function save(): void
{
$path = $this->photo->store('photos');
$this->reset('photo'); // Clear temporary upload
}
Package Integration
- livewire/livewire - Core framework
- wire-elements/modal - Modal dialogs
- rappasoft/laravel-livewire-tables - DataTables
- livewire/volt - Single-file components
Best Practices
- Use
wire:keyfor list items - Debounce search inputs:
wire:model.live.debounce.300ms - Use
#[Computed]for derived data - Keep components focused (single responsibility)
- Use events for cross-component communication
- Prefer
wire:navigatefor SPA-like navigation - Use loading states for better UX
Loading States
<!-- Show while any action runs -->
<div wire:loading>Loading...</div>
<!-- Show for specific action -->
<div wire:loading wire:target="save">Saving...</div>
<!-- Disable button while loading -->
<button wire:loading.attr="disabled">Submit</button>
<!-- Add class while loading -->
<div wire:loading.class="opacity-50">Content</div>
Related Commands
- /laravel-agent:livewire:make - Create Livewire components
Related Agent
- laravel-livewire - Livewire component specialist