Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Livewire Alert Laravel Package

jantinnerezo/livewire-alert

Livewire Alert integrates SweetAlert2 with Laravel Livewire so you can fire toasts, confirmation dialogs, and flash messages straight from your components using a simple fluent API. It handles the JavaScript wiring, keeping all your alert logic in PHP—no front-end code required.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire up once:

composer require jantinnerezo/livewire-alert
php artisan vendor:publish --tag=livewire-alert-config   # optional, for defaults

Place the alert host component once in your layout (typically just before </body>) — without it, every LivewireAlert::...->show() silently does nothing but log to the browser console:

@livewire('livewire-alert')

First use case — a save toast:

use Jantinnerezo\LivewireAlert\Facades\LivewireAlert;

public function save()
{
    $this->post->save();

    LivewireAlert::title('Saved')->success()->asToast()->show();
}

First new use case (v4.2) — a long-running task without flicker:

LivewireAlert::title('Importing...')->asLoading()->show();
// ... later, from a poll or job callback
LivewireAlert::text('50%')->update();
// ... when done
LivewireAlert::title('Import complete')->success()->update();
LivewireAlert::close();

Look first at the published config file — it holds the global defaults (position, timer, button labels, toast mode) that the fluent API inherits from. Then read the Alertable interface: it is the exact contract your components and any mocks deal with.

Implementation Patterns

Fluent chaining for one-shot notifications. The idiomatic call is a single statement: title()->text()->success()->position()->timer()->show(). Anything you don't specify comes from config. Use ->asToast() for non-blocking feedback, ->asQuestion() + confirm/dismiss handlers for destructive actions.

Question / confirmation flow. Pair an ask-alert with a Livewire listener so the actual work happens server-side after confirmation:

LivewireAlert::title('Delete this post?')
    ->asQuestion()
    ->confirmButton('Delete')
    ->onConfirm('destroy')
    ->show();

Live progress with asLoading() + wire:poll + update() (the headline v4.2 pattern). Open a spinner-preset alert, let a poll tick read state, and mutate the same alert in place:

public function start()
{
    $this->batchId = Bus::batch([...])->dispatch()->id;
    LivewireAlert::title('Processing...')->asLoading()->show();
}

public function checkProgress()
{
    $batch = Bus::findBatch($this->batchId);

    if ($batch->finished()) {
        LivewireAlert::title('Done')->text("{$batch->processedJobs()} jobs")->update();
        LivewireAlert::close();
        return;
    }

    LivewireAlert::title('Processing...')
        ->text($batch->progress().'%')
        ->update();
}

Keep the polling method tiny and never show() again inside it — the whole point is that the alert is already open.

Two update() dialects — pick deliberately.

  • Fluent emits only the properties you explicitly set; config defaults are not merged. Great for nudging the current alert forward (title, text, icon) without resetting buttons/timers.
  • Explicit payload takes the raw SweetAlert2 options array and is the right tool when you need to clear or fully reshape a key:
LivewireAlert::update(['title' => 'Retrying...', 'timer' => null, 'showConfirmButton' => false]);

Integration with job/batch callbacks. Since update() and close() are stateless, you can drive them from anywhere a Livewire request originates — a poll, a #[On] listener, or after a queued notification. The alert is addressed implicitly ("whatever is currently visible"), so the cleanest architecture is one long-lived alert per component instance, updated by key rather than re-created.

Phased multi-step flows. Move from spinner → progress → result in a single alert lifetime:

LivewireAlert::title('Uploading...')->asLoading()->show();     // step 1
LivewireAlert::title('Validating')->text('3 of 5')->update();   // step 2
LivewireAlert::title('All set')->success()->update();          // step 3

Gotchas and Tips

  • Fluent update() cannot unset things. Because it only emits explicitly-set options (no config merge), there is no way to remove a previously set timer, showConfirmButton, or icon fluently. Fall back to LivewireAlert::update([...]) with the explicit values.
  • Silent no-ops. update() and close() do nothing but a console.warn when no alert is visible. If your progress UI "never updates," first check you called show()/asLoading()->show() in the same page lifecycle — a full-page wire:navigate or redirect kills the SweetAlert instance.
  • Guards no longer throw. v4.2 changed guard behaviour so pre-call checks fail soft. Don't rely on exceptions to detect "no alert is open"; if a flow depends on it, track that state yourself in the component.
  • A stuck spinner is now a UX trap. asLoading() disables backdrop clicks (and is non-dismissable). If a job throws, the user is locked out of the UI until they reload. Always wrap in try/finally and guarantee a terminal update() or close():
try { $this->doWork(); }
catch (Throwable $e) {
    LivewireAlert::title('Failed')->text($e->getMessage())->error()->update();
    return;
}
LivewireAlert::close();
  • Order and batching. update() then close() in the same request can race the browser round-trip; the last state usually wins but the intermediate update may never paint. If you want the user to see the final state, update() in one request and close() on the next poll, or use ->timer() and let SweetAlert dismiss itself.
  • asLoading() overrides your config. It forces spinner + non-dismissable + backdrop-click-disabled, so position, timer, and button settings from config still apply, but anything that would let the user close it is suppressed by design.
  • Polling cost. update() sends a small options payload, but the containing Livewire request is a full round-trip. Don't poll faster than ~1s, and put the progress method on a dedicated component or wire:poll.2s so you aren't re-rendering a heavy view every tick.
  • Toasts vs modals for live updates. Live-updating a toast is technically possible but visually jarring (it may auto-dismiss mid-update). Use a persistent modal for update()-driven progress, toasts for fire-and-forget messages.
  • Alertable additions are additive but not free. New methods on the interface mean hand-rolled fakes/mocks implementing it will need asLoading(), close(), and update() added — check your test doubles after upgrading.
  • Debugging ladder for "the alert does nothing": (1) is @livewire('livewire-alert') in the layout of this page, (2) does the browser console show a console.warn (proves the bridge loaded and no alert was open), (3) is the component actually re-rendering on poll, (4) is a redirect or wire:navigate tearing down the DOM.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core