livewire/volt
Volt is a functional API for Livewire that supports single-file components, letting you write a component’s PHP logic and Blade template together in one file for a cleaner, more streamlined workflow.
Installation:
composer require livewire/volt
Volt integrates seamlessly with Livewire, so no additional configuration is required beyond ensuring Livewire is installed (livewire/livewire).
First Component: Generate a Volt component using the Artisan command:
php artisan make:volt Counter
This creates a single-file component (resources/views/livewire/counter.volt.php) with both PHP logic and Blade template in one file.
Basic Usage:
// resources/views/livewire/counter.volt.php
<div>
<button wire:click="increment">Count: <?php echo $count; ?></button>
</div>
<?php
class Counter extends Livewire\Component
{
public int $count = 0;
public function increment()
{
$this->count++;
}
}
Render in Blade:
@livewire('counter')
make:volt – Generate new Volt components.make:volt --class – Generate class-based Volt components (for Laravel 10+).Volt::mount() or Volt::route() for dynamic rendering.Volt’s strength lies in combining PHP logic and Blade templates in one file. This reduces context-switching and simplifies small-to-medium components.
<!-- resources/views/livewire/contact-form.volt.php -->
<div>
<form wire:submit.prevent="submit">
<input type="text" wire:model="name" placeholder="Name">
<textarea wire:model="message" placeholder="Message"></textarea>
<button type="submit">Send</button>
</form>
</div>
<?php
class ContactForm extends Livewire\Component
{
public string $name = '';
public string $message = '';
public function submit()
{
$this->validate([
'name' => 'required',
'message' => 'required|min:10',
]);
// Process form...
}
}
Use the Volt facade to mount components dynamically, especially useful for:
<?php if ($showComponent): ?>
<?php Volt::mount('counter'); ?>
<?php endif; ?>
Route::get('/dashboard', function () {
return Volt::route('dashboard-component');
});
Leverage Volt’s state options for advanced use cases:
<?php Volt::mount('user-profile', [
'userId' => 1,
'options' => [
'title' => 'User Profile',
'key' => 'user-profile-' . $userId,
'only' => ['name', 'email'], // Only sync these properties
],
]); ?>
Volt integrates with Laravel’s testing tools:
public function test_volt_component()
{
$this->livewire(Volt::class)
->assertSeeVolt('counter'); // Assert component is rendered
}
For larger components, use the --class flag:
php artisan make:volt UserProfile --class
This generates a separate PHP class (app/Livewire/UserProfile.php) with the template in resources/views/livewire/user-profile.blade.php.
View Path Configuration:
Ensure livewire.view_path in config/livewire.php points to resources/views (default). Volt relies on this for component resolution.
'view_path' => resource_path('views'),
Blade vs. PHP Syntax:
Volt files use .volt.php extension. Avoid mixing @php directives with raw PHP blocks—stick to one style per component for clarity.
Component Aliases:
If using custom view paths or namespaces, ensure aliases are configured in config/livewire.php:
'component_namespace' => 'App\\Livewire',
State Property Serialization: Volt’s state properties must be public. Avoid private/protected properties for reactive data:
// ❌ Avoid
protected $hidden = true;
// ✅ Use public
public bool $isHidden = false;
Route Caching Issues:
If you encounter Segmentation fault during route:cache, ensure Volt’s precompiler is compatible with your Laravel version (see #42).
Check Volt Logs:
Enable Livewire debugging in .env:
LIVEWIRE_DEBUG=true
This logs component lifecycle events to the browser console.
Precompiler Errors: If Volt fails to compile, clear cached views:
php artisan view:clear
php artisan cache:clear
State Not Updating:
Ensure properties are marked as public and not modified outside Livewire’s reactivity system (e.g., avoid $this->property = $value in non-wire methods).
Custom Precompiler: Override Volt’s precompiler logic by publishing and modifying the config:
php artisan vendor:publish --tag="volt-config"
Edit config/volt.php to customize compilation behavior.
Testing Helpers: Extend Volt’s testing methods by creating custom assertions:
use Livewire\Volt\Testing\VoltTestCase;
class CustomVoltTestCase extends VoltTestCase
{
public function assertVoltHasClass($selector, $class)
{
$this->assertStringContainsString($class, $this->getLivewireHtml());
}
}
Integration with Folio: For Folio-based projects, use Volt’s anonymous components:
Volt::mount('user-card', ['user' => $user], 'user-card');
Ensure the component name matches Folio’s expected namespace.
Avoid Heavy Logic in Render:
Offload complex logic to methods called via wire:click or wire:change to minimize re-renders.
Lazy-Load Components:
Use wire:ignore for non-reactive elements to reduce payload size:
<div wire:ignore>
<!-- Non-reactive content -->
</div>
Memoization: Cache expensive computations in properties:
public function getExpensiveData()
{
return $this->state->expensiveData ?? ($this->state->expensiveData = fetchData());
}
How can I help you explore Laravel packages today?