Installation
composer require wpstarter/livewire
Ensure your WordPress theme is built on the WpStarter framework (this package is a dependency of WpStarter).
Enqueue Livewire Scripts
In your theme's functions.php or a custom plugin:
add_action('wp_enqueue_scripts', function() {
wp_enqueue_script('livewire');
});
First Livewire Component
Create a component at wp-content/themes/your-theme/app/Livewire/YourComponent.php:
<?php
namespace App\Livewire;
use Livewire\Component;
class YourComponent extends Component
{
public $name = 'World';
public function render()
{
return view('livewire.your-component');
}
}
Create the Blade View
At wp-content/themes/your-theme/resources/views/livewire/your-component.blade.php:
<input wire:model="name" type="text">
<p>Hello, {{ $name }}!</p>
Use the Component in WordPress
In a template file (e.g., page-template.php):
<?php
use App\Livewire\YourComponent;
?>
<livewire your-component />
Replace a traditional WordPress form with Livewire for real-time validation and submission:
// app/Livewire/ContactForm.php
public $email;
public $message;
protected $rules = [
'email' => 'required|email',
'message' => 'required|min:10',
];
public function submit()
{
// Process form (e.g., save to DB or send email)
$this->reset('message'); // Clear message after submission
}
View (livewire/contact-form.blade.php):
<form wire:submit.prevent="submit">
<input wire:model="email" type="email" placeholder="Email">
<textarea wire:model="message" placeholder="Message"></textarea>
<button type="submit">Send</button>
@error('email') <span>{{ $message }}</span> @enderror
</form>
App\Livewire\Domain\Feature\Component (e.g., App\Livewire\Ecommerce\Cart\CartComponent).resources/views/livewire/domain/feature/component.blade.php.BaseFormComponent).add_shortcode('dynamic_content', function() {
return '<livewire dynamic-content-component />';
});
mount() and update Livewire state:
public function mount()
{
$this->posts = \WP_Query::newInstance()->posts;
}
sessionStorage for data that should persist across page reloads:
public $persistentValue;
public function mount()
{
$this->persistentValue = sessionStorage()->get('key', 'default');
}
public function save()
{
sessionStorage()->put('key', $this->persistentValue);
}
public function mount()
{
$this->data = get_transient('livewire_cache_key');
}
public function updatedData()
{
set_transient('livewire_cache_key', $this->data, HOUR_IN_SECONDS);
}
// app/Livewire/PostEditor.php
public $title;
public $content;
public $postId;
public function mount($postId = null)
{
if ($postId) {
$post = get_post($postId);
$this->title = $post->post_title;
$this->content = $post->post_content;
}
}
public function save()
{
wp_update_post([
'ID' => $this->postId ?? wp_insert_post([
'post_title' => $this->title,
'post_content' => $this->content,
'post_status' => 'draft',
]),
'post_title' => $this->title,
'post_content' => $this->content,
]);
}
public function mount()
{
add_action('wp_loaded', [$this, 'handleWpEvent']);
}
public function handleWpEvent()
{
// Logic tied to WordPress lifecycle
}
// Emit from component
$this->emit('customEvent', ['data' => 'value']);
// Listen in another component
protected $listeners = ['customEvent' => 'handleEvent'];
wp_enqueue_script in mount():
public function mount()
{
wp_enqueue_script('custom-script', get_template_directory_uri() . '/js/custom.js');
}
WordPress Nonce Validation
add_filter('wp_starter_livewire_excluded_routes', function($routes) {
return array_merge($routes, [
'livewire/update',
'livewire/lock',
]);
});
Plugin/Theme Conflicts
State Persistence
Blade vs. WordPress Template Tags
the_title(), get_header()) won’t work in Livewire Blade views. Use PHP directly or fetch data via WordPress APIs in the component class.Livewire + Gutenberg
@php tags to embed Livewire:
// Example: my-block.js
const el = wp.element.createElement;
const MyBlock = () => {
return el('div', { className: 'my-block' }, [
el('div', { dangerouslySetInnerHTML: { __html: '<livewire dynamic-content />' } }),
]);
};
Livewire Logs
Enable Livewire logging in wp-config.php:
define('WPSTARTER_LIVEWIRE_LOG', true);
Logs appear in /wp-content/debug/livewire.log.
Network Tab
/livewire/update).XHR Payloads Inspect Livewire’s XHR payloads to verify state updates:
{
"component": "your-component",
"data": {
"name": "New Value"
}
}
Hybrid Components Combine Livewire with WordPress widgets:
// app/Livewire/WidgetComponent.php
public function mount()
{
register_widget([$this, 'widget']);
}
public function widget($args)
{
return '<livewire widget-component />';
}
Performance
wire:ignore for non-interactive elements.wire:debounce.500ms to inputs to reduce server load:
<input wire:model.debounce.500ms="searchQuery">
Testing
wpstarter/livewire-testing for PHPUnit tests:
use Livewire\Testing\TestableLivewire;
public function test_component()
{
$component = TestableLivewire::render(YourComponent::class);
$component->set('name', 'Test');
How can I help you explore Laravel packages today?