- Cookbook
- modals-and-feedback
Modals and feedback
Open and close modals from Livewire, confirm with toasts, and keep people informed while things load.
Open and close a modal from PHP
Every modal listens to two browser events named after its id. Dispatch them from a Livewire action:
$this->dispatch('modal:edit-member:open');
$this->dispatch('modal:edit-member:close');
Open from PHP when the modal needs data first (fill the form, then open); otherwise open it in the browser with x-on:click="$modal('edit-member').showModal()"
and save a round trip.
Keep the modal inside its component
Put <x-ui.modal>
in the same Livewire component as the action that fills it. The modal stays in place in the page — the browser shows it on top anyway — so Livewire keeps updating its fields and its error messages.
A toast for every action that saves
People should never wonder whether it worked. Dispatch a toast at the end of the action, with what changed in the message.
$this->dispatch('toast', type: 'success', message: "{$project->name} created");
Put the toaster once in your layout: <x-ui.toaster />
.
A toast after a redirect
When the action redirects, flash the toast in the session: the next page shows it.
return redirect()->route('projects.show', $project)
->with('toast', ['type' => 'success', 'message' => 'Project created']);
Undo instead of "Are you sure?"
A toast can carry an action. Its button dispatches a Livewire event back to your component:
$this->dispatch('toast',
message: 'Project archived',
action: ['label' => 'Undo', 'event' => 'project-restore', 'params' => ['id' => $project->id]],
);
#[On('project-restore')]
public function restore(int $id): void
{
// The id comes back from the browser: find it again, check the policy.
}
The full pattern, with soft deletes and an undo window: Delete, then undo .
A toast that follows a long action
For an action that takes seconds, show a loading toast that turns into the result. From Alpine, wrap the Livewire call:
<x-ui.button x-on:click="$toast.promise($wire.export(), {
loading: 'Preparing the export…',
success: 'Export ready',
error: 'The export failed',
})">
Export
</x-ui.button>
Focus the first field
A modal form should be typed into right away. autofocus
on the first field does it when the modal opens:
<x-ui.input id="project-name" wire:model="name" autofocus />