>-
Livewire Development
When to Apply
Activate this skill when:
Creating or modifying Livewire components
Using wire: directives (model, click, loading, sort, intersect)
Implementing islands or async actions
Writing Livewire component tests
Documentation
Use search-docs for detailed Livewire 4 patterns and documentation.
Basic Usage
Creating Components
Single-file component (default in v4)
{{ $assist->artisanCommand('make:livewire create-post') }}
Multi-file component
{{ $assist->artisanCommand('make:livewire create-post --mfc') }}
Class-based component (v3 style)
{{ $assist->artisanCommand('make:livewire create-post --class') }}
With namespace
{{ $assist->artisanCommand('make:livewire Posts/CreatePost') }}
Converting Between Formats
Use php artisan livewire:convert create-post to convert between single-file, multi-file, and class-based formats.
Component Format Reference
Format
Flag
Structure
Single-file (SFC)
default
PHP + Blade in one file
Multi-file (MFC)
--mfc
Separate PHP class, Blade, JS, tests
Class-based
--class
Traditional v3 style class
View-based
⚡ prefix
Blade-only with functional state
Single-File Component Example
Livewire 4 Specifics
Key Changes From Livewire 3
These things changed in Livewire 4, but may not have been updated in this application. Verify this application's setup to ensure you follow existing conventions.
Use Route::livewire() for full-page components; config keys renamed: layout → component_layout, lazy_placeholder → component_placeholder.
wire:model now ignores child events by default (use wire:model.deep for old behavior); wire:scroll renamed to wire:navigate:scroll.
Component tags must be properly closed; wire:transition now uses View Transitions API (modifiers removed).
JavaScript: $wire.$js('name', fn) → $wire.$js.name = fn; commit/request hooks → interceptMessage()/interceptRequest().
New Features
Component formats: single-file (SFC), multi-file (MFC), view-based components.
Islands (@island) for isolated updates; async actions (wire:click.async, #[Async]) for parallel execution.
Deferred/bundled loading: defer, lazy.bundle for optimized component loading.
Feature
Usage
Purpose
Islands
@island(name: 'stats')
Isolated update regions
Async
wire:click.async or #[Async]
Non-blocking actions
Deferred
defer attribute
Load after page render
Bundled
lazy.bundle
Load multiple together
New Directives
wire:sort, wire:intersect, wire:ref, .renderless, .preserve-scroll are available for use.
data-loading attribute automatically added to elements triggering network requests.
Directive
Purpose
wire:sort
Drag-and-drop sorting
wire:intersect
Viewport intersection detection
wire:ref
Element references for JS
.renderless
Component without rendering
.preserve-scroll
Preserve scroll position
Best Practices
Always use wire:key in loops
Use wire:loading for loading states
Use wire:model.live for instant updates (default is debounced)
Validate and authorize in actions (treat like HTTP requests)
Configuration
smart_wire_keys defaults to true; new configs: component_locations, component_namespaces, make_command, csp_safe.
Alpine & JavaScript
wire:transition uses browser View Transitions API; $errors and $intercept magic properties available.
Non-blocking wire:poll and parallel wire:model.live updates improve performance.
For interceptors and hooks, see reference/javascript-hooks.md.
Testing
Livewire::test(Counter::class)
->assertSet('count', 0)
->call('increment')
->assertSet('count', 1);
Verification
Browser console: Check for JS errors
Network tab: Verify Livewire requests return 200
Ensure wire:key on all @foreach loops
Common Pitfalls
Missing wire:key in loops → unexpected re-rendering
Expecting wire:model real-time → use wire:model.live
Unclosed component tags → syntax errors in v4
Using deprecated config keys or JS hooks
Including Alpine.js separately (already bundled in Livewire 4)don't have the plugin yet? install it then click "run inline in claude" again.