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

Notifications Laravel Package

filament/notifications

Filament Notifications adds database-backed user notifications to Filament apps, including a topbar bell with unread counts, a notification list, and Livewire components for sending and managing alerts through Laravel’s notification system.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and align versions. filament/notifications is a split package from the Filament monorepo, so pin it to the same major as anything else Filament you run (^3.0 with Filament v3 / Livewire 3, ^4.0 with v4). Mixing majors pulls duplicate support packages and breaks the render.

composer require filament/notifications:"^4.0"

Wire the assets and the render target. Two things must exist in your layout or you get silence:

<head>
    @filamentStyles   {{-- or <link> tags after php artisan filament:assets --}}
</head>
<body>
    {{ $slot }}

    <x-filament-notifications::notifications />  {{-- the toast host; renders a Livewire component --}}
    @filamentScripts                             {{-- bundles Alpine + the notification JS --}}
</body>

Fire the first one. It is a static factory, not a trait on your component:

use Filament\Notifications\Notification;

public function save(): void
{
    $this->record->save();

    Notification::make()
        ->title('Saved')
        ->body('The record was updated.')
        ->success()
        ->send();
}

Where to look first. In vendor/filament/notifications/: src/Notification.php (the whole fluent API lives here — read the method list, it answers 80% of questions), src/Livewire/Notifications.php (the toast host), src/Livewire/DatabaseNotifications.php (the polling bell), and resources/views/. Then the docs page on filamentphp.com for the current version.

First real use case. Rip out every session()->flash('status', ...) in a CRUD screen and replace it with Notification::make()->success()->send() in the Livewire action. That's a one-afternoon migration and it is where the package earns its keep.

Implementation Patterns

Status helpers over manual colouring. ->success(), ->danger(), ->warning(), ->info() set colour + icon in one call. Use ->color(), ->icon(), ->iconColor() only when you need something off-palette.

Wrap the factory once, not everywhere. Domain code shouldn't import a UI class. A thin helper keeps call sites short and makes a future swap trivial:

// app/Support/Notify.php
final class Notify
{
    public static function saved(string $subject): void
    {
        Notification::make()->title("{$subject} saved")->success()->send();
    }

    public static function failed(string $message): void
    {
        Notification::make()->title('Something went wrong')->body($message)
            ->danger()->persistent()->send();
    }
}

Actionable toasts. Notifications are Livewire components, so their actions can call back into your app — good for undo, "view record", retry:

Notification::make()
    ->title('Import queued')
    ->actions([
        Action::make('undo')->button()->dispatch('undo-import', importId: $id),
    ])
    ->persistent()
    ->send();

Persistent/database notifications for anything the user might miss. Toasts are ephemeral and tied to the current request. If the event can happen while the user is on another page (queued job finished, approval requested), use the database channel:

  1. php artisan notifications:table && php artisan migrate (Laravel's standard table — Filament stores payload in data).
  2. On your User: use Filament\Notifications\Concerns\DatabaseNotifications; (and implement Notifiable).
  3. Render the bell: <x-filament-notifications::database-notifications /> in the topbar, optionally with ->pollingInterval('30s').
  4. Send with ->sendToDatabase($user) instead of ->send().

Keep the queue boundary clean. Don't call send() from inside a queued job and expect a toast — there's no Livewire request to attach it to. From a job, either write a database notification or dispatch a browser event the host listens for; the pragmatic pattern is: job writes to the database, the polling bell picks it up.

Rich content via custom views. ->view('notifications.import-progress', ['progress' => $p]) is the escape hatch when title/body isn't enough (progress bars, previews). Note the tailwind caveat below.

Test it like any Livewire action. With Filament's test helpers you get assertNotified():

livewire(EditPost::class)
    ->fillForm([...])
    ->call('save')
    ->assertNotified('Saved');

Assert the notification type/body, not the markup — markup moves between minor versions.

Gotchas and Tips

Nothing renders? Check three things in order: @filamentScripts is present, <x-filament-notifications::notifications /> is in the layout outside your Livewire component's root, and the notification was sent within a request that reaches that layout. A missing host component is the single most common "it doesn't work" report.

Alpine double-init. @filamentScripts ships Alpine. If your app already loads Alpine from a separate <script>, you get two instances and event handlers fire twice. Either let Filament own Alpine or set the appropriate config flag — don't ship both.

It is a heavier dependency than the name suggests. Installing standalone pulls filament/support, filament/actions, and friends. For a Blade-only app this is a real cost; for an app already on Filament it's free. Check composer why filament/support before adopting in a lean project.

Sending outside a Livewire request (a controller, a redirect) works via the session flash, but it only surfaces when the notification host re-mounts. With wire:navigate SPA transitions this is usually fine; with cached full-page responses it can vanish. When in doubt, prefer database notifications for cross-request events.

Don't reuse a Notification instance. Each make() gets an id and re-sending the same object in one request can collapse into one toast. Always build fresh inside loops.

Custom views + Tailwind purge. Classes you use in a ->view() file that never appear in your compiled CSS get purged. Either safelist them or reuse the package's existing classes. This bites hardest on one-off notification designs.

Persistent vs. duration. ->persistent() disables auto-dismiss; combine with an explicit close action for anything that needs acknowledgement. Conversely ->duration(2000) for low-stakes confirmations. Watch z-index if you stack notifications over Filament modals — check in the browser, not in code.

Assets after upgrade. If you publish rather than serve from vendor, re-run php artisan filament:assets (or vendor:publish --tag=filament-assets) on every package upgrade or you'll debug stale CSS for an hour.

Debugging path. Browser console: confirm the Livewire component filament-notifications::notifications is on the page and receiving events. If the component exists but shows nothing, inspect the component's notifications property after the action. If it's empty there, the problem is server-side (the send() never ran — check early returns, exceptions swallowed by a try/catch, or the wrong guard).

No first-party broadcasting. Real-time push (Echo/Pusher) isn't wired for you; you either poll database notifications, dispatch a JS event manually, or build the Echo listener yourself. Plan for polling unless you have a hard latency requirement.

Extension points worth knowing. Custom ->view(), ->actions(), config for default duration/position, and swapping the database notification model. Anything deeper — custom animation, non-Filament styling system — is where you start paying the "pixel-perfect" tax the package deliberately doesn't cover.

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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr