Livewire 3.6.10 with Laravel 11: wire:model not binding input value after page refresh

I'm working with Laravel 11
, Livewire 3.6.10
, and Alpine.js
(properly configured). I'm encountering an issue where wire:model
doesn't bind the value to an input field
after a page refresh, even though the variable is correctly set in the component.
What Works
- Items are listed correctly in a table.
- Adding a new item works perfectly.
- Clicking "Edit" immediately after adding an item shows the form with values populated (including the input field).
The Issue
If I refresh the page and then click "Edit" on an item:
- The variable
{{ $name }}
displays correctly. - But the input field bound with
wire:model="name"
does not show the value.
Code Snippets
<table class="min-w-full">
<thead>
<tr>
<th>#NO</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
@foreach ($list as $item)
<tr>
<td>{{ $loop->iteration }}</td>
<td>{{ $item->name }}</td>
<td>
<button wire:click="edit({{ $item->id }})">Edit</button>
</td>
</tr>
@endforeach
</tbody>
</table>
Edit Form
{{ $name }} <!-- Displays correctly -->
<form wire:submit.prevent="{{ $isEdit ? 'update' : 'store' }}">
<input type="text" wire:model="name">
</form>
Edit method
public function edit($id)
{
$inventory = ModelsInventory::findOrFail($id);
$this->inventory_id = $id;
$this->name = $inventory->name;
}
Debugging Summary
$name
is correctly populated.{{ $name }}
displays the expected value.- However,
<input wire:model="name">
does not reflect the value after a page refresh.
Question
Why is the value not binding to the input via wire:model
after a page refresh
, even though the component variable is correctly populated?
Note: the project is created with starter kit, laravel breeze
, it has livewire
and alpine
configured.
app.js
import Alpine from 'alpinejs'
import persist from '@alpinejs/persist'
import './bootstrap'; // assuming Livewire's stuff is here
// Only register Alpine once (before Livewire boots it)
window.Alpine = Alpine
Alpine.plugin(persist)
There are no browser console errors.
I have found a code snippet online that says as follow
Force DOM Update with Alpine
<input type="text"
wire:model="name"
x-data
x-init="$nextTick(() => { $el.value = '{{ $name }}' })">
I have tried this snippet, surprisingly it worked.
But the problem is that, I don't want these extra things in my input field, I want to use only wire:model="name"
and it should work.
Answer
Since you're using Livewire 3.6.10, Laravel 11, and Alpine.js (which is already configured), the best solution to ensure proper two-way binding after page refresh is:
Use Alpine's @entangle
to Bridge Livewire and DOM
Replace this:
<input type="text" wire:model="name">
With this:
<input type="text" x-data x-model="@entangle('name')">
Working Example:
<form wire:submit.prevent="{{ $isEdit ? 'update' : 'store' }}">
<input type="text" x-data x-model="@entangle('name')" class="border rounded p-1">
</form>
Enjoyed this article?
Check out more content on our blog or follow us on social media.
Browse more articles