Solution:
This is a known change in Livewire v3. In Livewire v2, <input type="hidden"> fields bound with wire:model or wire:model.live were automatically tracked and updated by Livewire. However, in Livewire v3, hidden inputs are intentionally ignored unless they have a wire:model binding and their value is changed via JavaScript or some manual event, due to performance reasons and to avoid unnecessary dom updates.
Why doesn’t it work?
- Hidden fields don't trigger user events (like
inputorchange), so Livewire doesn’t detect any value changes unless you set the value programmatically. - With
type="text", user input is possible (and events fire), so Livewire notices and updates the value.
How to fix:
You should use wire:model.defer instead of wire:model.live on hidden fields, and set the value via Livewire (not just via the DOM). This way, hidden inputs' values will stay in sync via the Livewire property, and will be sent to the server when the form is submitted.
Example:
<input type="hidden" name="{{ $fieldName }}" wire:model.defer="item_key">
Or, if you want it to update on user or programmatic input, you can use Alpine.js to trigger an update:
<input type="hidden" name="{{ $fieldName }}"
x-data
x-model="$wire.item_key"
wire:model.defer="item_key">
Best Practice:
- Use
wire:model.deferfor hidden fields. - If you need to change the value dynamically, always update the Livewire property (
item_key). - Don’t rely only on changing the DOM value of a hidden input. Update the property in the component instead.
References:
Summary:
Livewire v3 doesn't track hidden fields with wire:model.live because there's no event to trigger updates. Always use wire:model.defer on hidden inputs, and update their values through Livewire, not just the DOM.