Advertisement
Advertisement
Advertisement
Advertisement
Advertisement
Navigation
AI Analysis
Livewire 4 Upgrade Plan
Overview
This document outlines the comprehensive plan for upgrading RiftSurge from Livewire 3 to Livewire 4. Livewire 4 is now officially released and brings significant improvements to animations, performance, and developer experience.
Official Resources:
π Implementation Status
Completed β
|
Phase
|
Task
|
Status
|
|---|---|---|
|
1.1
|
Update composer.json to Livewire
|
β Done
|
|
1.2
|
Update Flux UI to
|
β Done
|
|
1.3
|
Migrate
|
β Done (14 files)
|
|
1.4
|
Fix
|
β Done (2 files)
|
|
2.1
|
Add
|
β Done (6 files)
|
|
2.2
|
Improve loading states with
|
β Done (4 files)
|
|
4.0
|
Implement lazy loading for heavy components
|
β Done (13 components)
|
|
7.0
|
Migrate
|
β Done (5 files)
|
Remaining π
|
Phase
|
Task
|
Status
|
|---|---|---|
|
1.0
|
Run
|
β³ Requires local env
|
|
3.0
|
Test all updated components
|
β³ After composer update
|
|
5.0
|
Add Islands for static content
|
βΈοΈ Not applicable (see below)
|
|
6.0
|
Implement
|
π Optional (current pattern is fine)
|
Breaking Changes Audit
β Fixed
|
Pattern
|
Status
|
Notes
|
|---|---|---|
|
|
β Fixed
|
All 14 files migrated to
|
|
|
β Fixed
|
Updated to use array destructuring
|
|
|
β N/A
|
Not used (using
|
|
|
β N/A
|
Not used
|
|
|
β N/A
|
Not used
|
|
|
β N/A
|
Not used (now default behavior)
|
|
|
β N/A
|
Not used
|
β οΈ Still Supported (Optional Migration)
|
Pattern
|
Files
|
Notes
|
|---|---|---|
|
|
β Migrated
|
All 5 files now use
|
|
|
4 files
|
Can migrate to
|
|
|
2 files
|
Can migrate to
|
|
|
3 files
|
Used for dynamic Echo listeners, still valid
|
Patterns Already Using Modern Syntax β
|
Pattern
|
Status
|
|---|---|
|
|
β Correct
|
|
|
β Correct
|
|
|
β Correct
|
|
|
β Some components already use this
|
|
|
β Correct
|
|
|
β Correct
|
How to Complete the Upgrade
1. Pull the changes
git pull origin cursor/livewire-4-upgrade-61fb
2. Update all dependencies (Livewire 4 + Flux UI)
composer update livewire/livewire livewire/flux livewire/flux-pro --with-all-dependencies
3. Run Pint to format any changes
vendor/bin/pint --dirty
4. Run tests to verify
php artisan test
5. Test manually in the browser
Key Livewire 4 Features to Leverage
1. wire:transition (Implemented β
)
Smooth enter/leave animations for conditionally rendered elements:
@if($showModal)
Modal content
@endif
2. Loading State Improvements (Implemented β )
New delay modifiers prevent UI flashing:
Saving...
3. wire:stream (Planned)
Perfect for AI-generated content streaming:
{{ $aiResponse }}
4. Lazy Loading (Implemented β )
Defer component loading until visible with skeleton placeholders:
Loading skeleton...
Implemented in:
- Surge Hub (9 components): improvement-trajectory, team-health-dashboard, strategic-intel, player-spotlight, weekly-podcast, performance-pulse, daily-missions, role-transition-context, playstyle-mismatch-alerts
- Dashboard (4 components): upcoming-scrims, daily-message, comps, recent-activity
5. Islands (Evaluated - Not Applicable)
After analysis, Islands are not recommended for this codebase because:
1. Most components are interactive - Dashboard widgets, Surge Hub components, and other panels have significant user interactions (buttons, modals, forms) that require immediate hydration
2. Lazy loading provides similar benefits - We've already implemented lazy loading with skeleton placeholders for 13 heavy components, which provides the same initial page load performance benefits
3. Alpine.js state - Many components use @entangle, x-data, and complex Alpine state that wouldn't work well with deferred hydration
Islands are best for:
- Tooltips that appear on hover
- Help dropdowns that expand on click
- Navigation menus that open on interaction
- Static info panels that become interactive on focus
For this app, lazy loading is the better pattern because it defers component loading entirely until the component is in view, rather than deferring hydration of already-rendered HTML.
Current State Analysis
Codebase Statistics
|
Pattern
|
Count
|
Files
|
|---|---|---|
|
Livewire Components
|
97+
|
|
|
|
211+
|
54 files
|
|
|
220+
|
32 files
|
|
|
10+
|
10 files
|
|
|
27+
|
4 files
|
|
|
10+
|
5 files
|
|
|
14
|
14 files
|
|
|
20
|
20 files
|
|
Echo integrations
|
8
|
8 files
|
Current Patterns in Use
- Event Dispatching: Using
$this->dispatch()(β correct pattern) - Computed Properties: Using
#[Computed]attribute (β correct pattern) - Event Listeners: Mix of
protected $listenersarray and#[On()]attributes - Loading States: Heavy use of
wire:loading,wire:loading.attr,wire:loading.class,wire:target - Real-time: Echo integration with
#[On('echo:...')]listeners - Alpine Integration:
@entangle,x-transition,$wire
Phase 1: Dependency Upgrade & Compatibility Check
1.1 Update Composer Dependencies
Update Livewire to v4
composer require livewire/livewire:^4.0
Flux UI should be compatible - verify version
composer require livewire/flux:^2.2 livewire/flux-pro:^2.6
1.2 Breaking Changes to Address
Based on Livewire 4 upgrade documentation:
Property Visibility (CRITICAL)
Livewire 4 requires public properties to be used with wire:model. Check all components for protected/private properties bound to forms.
Files to audit:
- All components using
wire:model - Components with form data
Event Listener Syntax
The protected $listeners array is deprecated. All listeners should use the #[On()] attribute.
Files requiring update (14 files):
app/Livewire/Dashboard.php
app/Livewire/Team/Show.php
app/Livewire/Stats/Show.php
app/Livewire/NotificationManager.php
app/Livewire/Scrims/CreatePosting.php
app/Livewire/Scrims/Find.php
app/Livewire/DraftInterface.php
app/Livewire/Games/Show.php
app/Livewire/Roster/Show.php
app/Livewire/Comps/BansKanban.php
app/Livewire/Comps/ChampionsKanban.php
app/Livewire/Comps/Bans.php
app/Livewire/Comps/Create.php
Example migration:
// Before (Livewire 3 - deprecated)
protected $listeners = [
'go-to-profile' => 'goToProfile',
'go-to-opgg' => 'goToOpgg',
];
// After (Livewire 4)
use Livewire\Attributes\On;
#[On('go-to-profile')]
public function goToProfile() { ... }
#[On('go-to-opgg')]
public function goToOpgg() { ... }
Alpine.js Version
Livewire 4 includes Alpine.js v3.14+. Ensure no manual Alpine imports conflict.
Phase 2: New Loading States Implementation
2.1 Overview of New Loading API
Livewire 4 introduces a more powerful and cleaner loading states API. Key improvements:
wire:loading.classwith better specificitywire:loading.delaywith configurable delays (e.g.,wire:loading.delay.500ms)- Better targeting with
wire:target - New skeleton loading patterns
2.2 Files to Upgrade (32 files with wire:loading)
High-priority components (complex loading states):
1. livewire/games/fetch-game.blade.php - Game fetching with multiple loading states
2. livewire/roster/show.blade.php - 51 loading state usages
3. livewire/dashboard/podcast-widget.blade.php - 11 loading states
4. livewire/team/show.blade.php - 41 loading states
5. livewire/scrims/find.blade.php - 16 loading states
2.3 New Loading Patterns to Implement
Delay Modifiers
{{-- Show loading after 200ms delay to prevent flash --}}
Loading...
{{-- Different delay thresholds --}}
... {{-- 50ms --}}
... {{-- 100ms --}}
... {{-- 150ms --}}
... {{-- 300ms --}}
... {{-- 500ms --}}
... {{-- 1000ms --}}
Skeleton Loading Pattern
{{-- New skeleton loading for better UX --}}
{{ $actualContent }}
Loading States with Actions
{{-- Loading for specific actions --}}
Phase 3: Wire Transition (Animations)
3.1 Overview
Livewire 4's wire:transition replaces the need for both Alpine.js x-transition AND CSS transition- classes in many cases, providing smoother DOM morphing animations.
3.2 Transition Statistics
|
Type
|
Count
|
Files
|
|---|---|---|
|
CSS
|
1,023+
|
152 files
|
|
Alpine
|
27+
|
4 files
|
|
Total candidates
|
1,050+
|
152 files
|
3.3 Files with Alpine x-transition
resources/views/livewire/persistent-podcast-player.blade.php (12 usages)
resources/views/components/trial-expiration-banner.blade.php (6 usages)
resources/views/components/podcast-player.blade.php (3 usages)
resources/views/components/subscription-expired-banner.blade.php (6 usages)
3.4 High-Impact CSS Transition Files
Files with most CSS transitions that may benefit from wire:transition:
|
File
|
CSS Transitions
|
Priority
|
|---|---|---|
|
|
40
|
HIGH
|
|
|
39
|
HIGH
|
|
|
34
|
MEDIUM
|
|
|
32
|
HIGH
|
|
|
23
|
MEDIUM
|
|
|
23
|
HIGH
|
|
|
23
|
MEDIUM
|
|
|
22
|
HIGH
|
|
|
21
|
LOW
|
|
|
19
|
HIGH
|
3.5 When to Migrate CSS Transitions
MIGRATE to wire:transition:
- Elements shown/hidden via
@ifwith Livewire state - Elements controlled by
wire:loading - Lists that update via Livewire (with
wire:key)
KEEP CSS transitions:
- Hover effects (
hover:scale-105) - Focus states (
focus:ring-2) - Active states (
active:scale-95) - Permanent decorative animations
- Alpine-controlled visibility (use x-transition instead)
3.6 Migration Pattern for CSS Transitions
{{-- BEFORE: CSS transition on Livewire-controlled element --}}
@if($showPanel)
Panel content
@endif
{{-- AFTER: wire:transition handles enter/leave animation --}}
@if($showPanel)
Panel content
@endif
{{-- BEFORE: CSS transition on wire:loading element --}}
Save
{{-- AFTER: wire:transition for smoother morphing --}}
Save
3.3 Migration Examples
Before (Alpine x-transition)
x-transition:enter="transition ease-out duration-300"
x-transition:enter-start="opacity-0 scale-95"
x-transition:enter-end="opacity-100 scale-100"
x-transition:leave="transition ease-in duration-200"
x-transition:leave-start="opacity-100 scale-100"
x-transition:leave-end="opacity-0 scale-95">
After (Livewire wire:transition)
{{-- Using wire:transition for Livewire-controlled DOM updates --}}
@if($showModal)
@endif
3.4 Custom Animation Classes
{{-- Custom transition with specific duration --}}
...
{{-- Fade + scale combination --}}
...
{{-- Slide transitions --}}
...
...
3.5 Components to Enhance with wire:transition
Dashboard widgets:
livewire/dashboard/podcast-widget.blade.php- Add smooth transitions for state changeslivewire/dashboard/insights.blade.php- Transition between loading/loaded stateslivewire/dashboard/daily-message.blade.php- Animate message updates
Game/Scrim flows:
livewire/games/show.blade.php- Smooth transitions for game stateslivewire/scrims/confirm.blade.php- Better confirmation animations
Notification system:
livewire/notification-manager.blade.php- Enhanced notification animations
Phase 4: Livewire Islands
4.1 Overview
Islands allow you to isolate parts of your page that update independently, dramatically improving performance for complex pages.
4.2 Ideal Candidates for Islands
Dashboard Page (Dashboard.php):
The dashboard loads multiple independent widgets. Each can be an island:
{{-- Dashboard with Islands --}}
{{-- Left Column --}}
@island
@endisland
@island
@endisland
@island
@endisland
{{-- Right Column --}}
@island
@endisland
@island
@endisland
@island
@endisland
Surge Hub (Surge/Hub.php):
Complex page with many AI-powered widgets - perfect for islands:
{{-- Surge Hub with Islands for independent widget updates --}}
@island
@endisland
@island
@endisland
@island
@endisland
@island
@endisland
4.3 Benefits of Islands
1. Reduced Re-renders: Only the island updates, not the entire page
2. Better Performance: Smaller payloads for each update
3. Improved UX: Smoother experience with isolated updates
4. Parallel Loading: Islands can load/refresh independently
4.4 Pages to Convert to Islands
|
Page
|
Components
|
Priority
|
|---|---|---|
|
Dashboard
|
10 widgets
|
HIGH
|
|
Surge Hub
|
12 AI widgets
|
HIGH
|
|
Team Show
|
5 sections
|
MEDIUM
|
|
Player Stats
|
4 tabs
|
MEDIUM
|
|
Roster Show
|
3 tabs
|
MEDIUM
|
Phase 5: New Features to Implement
5.1 Lazy Loading Components
{{-- Lazy load heavy components --}}
{{-- With placeholder --}}
5.2 Teleport
For modals and overlays that need to render at document root:
{{-- Teleport modal to body to avoid z-index issues --}}
@teleport('body')
@endteleport
5.3 Form Objects (New in Livewire 4)
Create dedicated form classes for complex forms:
// app/Livewire/Forms/PlayerForm.php
namespace App\Livewire\Forms;
use Livewire\Form;
class PlayerForm extends Form
{
public string $riot_id = '';
public string $role = '';
protected function rules(): array
{
return [
'riot_id' => 'required
string
regex:/^.+#.+$/',
'role' => 'required
in:top,jungle,mid,adc,support',
];
}
protected function messages(): array
{
return [
'riot_id.regex' => 'Please enter a valid Riot ID (e.g., Faker#KR1)',
];
}
}
// Usage in component
class AddPlayer extends Component
{
public PlayerForm $form;
public function save()
{
$this->form->validate();
// Process $this->form->riot_id, $this->form->role
}
}
5.4 Wire Navigate Improvements
{{-- Prefetch on hover for faster navigation --}}
View Profile
{{-- Prefetch all links --}}
Phase 6: Testing Strategy
6.1 Test Updates Required
Update existing Livewire tests to use new testing methods:
// Before
Livewire::test(Dashboard::class)
->assertSet('user', $user);
// After (Livewire 4 - same API, verify compatibility)
Livewire::test(Dashboard::class)
->assertSet('user', $user);
6.2 New Test Patterns
// Test loading states
Livewire::test(FetchGame::class, ['game' => $game])
->call('searchGame')
->assertDispatched('notify');
// Test islands independently
Livewire::test(PodcastWidget::class)
->call('requestGeneration')
->assertSet('optimisticGenerating', true);
6.3 Run Test Suite
Run all Livewire-related tests
php artisan test --filter=Livewire
Run specific component tests
php artisan test tests/Feature/Livewire/
Phase 7: Implementation Checklist
Week 1: Foundation
- [ ] Update
composer.jsonto require Livewire 4 - [ ] Run
composer update livewire/livewire - [ ] Verify Flux UI compatibility
- [ ] Run test suite to identify breaking changes
- [ ] Fix any immediate compatibility issues
Week 2: Listener Migration
- [ ] Migrate
Dashboard.phplisteners to#[On()] - [ ] Migrate
Roster/Show.phplisteners - [ ] Migrate
Team/Show.phplisteners - [ ] Migrate
Stats/Show.phplisteners - [ ] Migrate remaining 10 components with
$listeners
Week 3: Loading States Enhancement
- [ ] Update
fetch-game.blade.phpwith new loading patterns - [ ] Update
roster/show.blade.phploading states - [ ] Update
podcast-widget.blade.phploading states - [ ] Add loading delays to prevent flash
- [ ] Implement skeleton loaders where appropriate
Week 4: Transitions & Animations
- [ ] Replace
x-transitionwithwire:transitionwhere applicable - [ ] Add
wire:transitionto notification components - [ ] Add
wire:transitionto modal components - [ ] Add
wire:transitionto dashboard widgets - [ ] Remove redundant Alpine transition code
Week 5: Islands Implementation
- [ ] Convert Dashboard to use Islands
- [ ] Convert Surge Hub to use Islands
- [ ] Convert Team Show page to use Islands
- [ ] Performance testing and optimization
- [ ] Document island patterns for team
Week 6: New Features & Polish
- [ ] Implement lazy loading for heavy components
- [ ] Add Form Objects for complex forms
- [ ] Implement wire:navigate prefetching
- [ ] Final testing and QA
- [ ] Update documentation
Breaking Changes Quick Reference
|
Change
|
Status
|
Notes
|
|---|---|---|
|
|
β οΈ UPDATE
|
Use
|
|
Property visibility
|
β CHECK
|
Ensure public for wire:model
|
|
Alpine.js bundled
|
β CHECK
|
Remove manual Alpine imports
|
|
Event names
|
β CHECK
|
Use kebab-case
|
|
|
β CHECK
|
|
Resources
- Livewire 4 Installation
- Livewire 4 Upgrading Guide
- Livewire 4 Loading States
- Livewire 4 Islands
- Livewire 4 Transitions
Rollback Plan
If critical issues are discovered:
1. Revert composer.json to livewire/livewire:^3.0
2. Run composer update livewire/livewire
3. Test critical paths
4. Document issues for future attempt
Last Updated: January 2026 Author: Claude (AI Assistant)
On this page
Advertisement