marcorieser/statamic-livewire
Bring Laravel Livewire to Statamic with seamless integration for interactive, reactive components inside your Statamic sites. Build dynamic UIs without heavy JavaScript, use familiar Livewire patterns, and keep content and frontend working smoothly together.
Installation
composer require marcorieser/statamic-livewire
Publish the config (if needed):
php artisan vendor:publish --provider="Marcorieser\StatamicLivewire\StatamicLivewireServiceProvider" --tag="config"
Register the Livewire Service Provider
Add to config/app.php under providers:
Marcorieser\StatamicLivewire\StatamicLivewireServiceProvider::class,
First Use Case: Embedding a Livewire Component in Antlers
In a Statamic template (.antlers.html):
{{ livewire:my-component property="value" }}
Or in Blade:
@livewire('my-component', ['property' => 'value'])
Create a Basic Livewire Component
php artisan make:livewire MyComponent
Example component (app/Http/Livewire/MyComponent.php):
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class MyComponent extends Component
{
public $property = 'default';
public function render()
{
return view('livewire.my-component');
}
}
Render the Component
Create resources/views/livewire/my-component.blade.php:
<div>
<input wire:model="property" type="text">
<p>Current value: {{ $property }}</p>
</div>
Livewire\Component and bind to Statamic’s $data or $errors.public $title;
public $content;
public function mount()
{
$this->title = request('title', '');
$this->content = request('content', '');
}
public function save()
{
$entry = Entry::make();
$entry->title = $this->title;
$entry->content = $this->content;
$entry->save();
}
{{ livewire:custom-entry-form entry_id="{{ entry.id }}" }}
wire:model to sync with Statamic’s $data.<div>
<input wire:model="data.title" type="text">
<div wire:ignore>
{{ $data->title->toHtml() }}
</div>
</div>
{{ entry }} object.wire:poll to refresh data periodically.public function poll()
{
$this->stats = Stats::latest()->first();
}
<div wire:poll.5000ms>
{{ $stats->value }}
</div>
Collection facade inside Livewire.public $search = '';
public function getEntriesProperty()
{
return Collection::query()
->where('title', 'like', "%{$this->search}%")
->get();
}
<input wire:model="search" type="text">
@foreach($entries as $entry)
<div>{{ $entry->title }}</div>
@endforeach
{{ livewire: }} inside Antlers and pass dynamic data via wire:model.{{ livewire:user-profile user="{{ user }}" }}
public $user;
public function mount($user)
{
$this->user = User::find($user);
}
Statamic Asset Handling
asset() helper or Statamic’s {{ url }} tag inside Livewire views for assets.<img src="{{ asset('images/' . $this->image) }}" alt="">
Form Submission with Statamic CSRF
@csrf
Livewire + Statamic Validation
use Illuminate\Validation\Rule;
public function rules()
{
return [
'title' => ['required', Rule::unique('entries')->ignore($this->entry)],
];
}
Livewire Middleware
handle():
public function handle()
{
if (!auth()->check()) {
return redirect()->route('login');
}
}
Testing
TestCase:
public function test_component()
{
$this->actingAs($user)
->livewire(MyComponent::class)
->assertSee('Expected Text');
}
Caching Conflicts
{{ cache:off }} in Antlers:
{{ cache:off }}
{{ livewire:my-component }}
{{ /cache:off }}
Livewire + Antlers Syntax Clashes
{{ }}) may conflict with Livewire’s Blade directives.{{ livewire: }} in Antlers and escape Blade tags with @verbatim if needed:
@verbatim
@livewire('my-component')
@endverbatim
State Persistence Across Requests
SESSION_DRIVER is consistent (e.g., database or file) in .env.Asset Pipeline Conflicts
@vite directives:
@vite(['resources/js/app.js', 'resources/css/app.css'])
Livewire + Statamic Entry Data Binding
$entry->data may cause serialization errors.wire:model with a getter/setter:
public function getTitleProperty()
{
return $this->entry->title ?? '';
}
public function setTitleProperty($value)
{
$this->entry->title = $value;
}
Livewire Wire:ignore
wire:ignore on dynamic content (e.g., iframes, third-party scripts) to avoid reactivity issues.Log Livewire Events
public function mounting()
{
\Log::info('Component mounted');
}
public function hydrating()
{
\Log::info('Component hydrated');
}
Statamic Entry Events
EntrySaved) to sync Livewire state:
Event::listen(EntrySaved::class, function ($event) {
// Update Livewire component state
});
Clear Livewire Cache
php artisan livewire:discover
php artisan view:clear
Check for JavaScript Errors
F12) to check for JS errors that may block reactivity.Livewire
How can I help you explore Laravel packages today?