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

Filament Notification Laravel Package

iracode-com/filament-notification

iracode-com/filament-notification is a lightweight Filament plugin for adding notification support to Laravel admin panels, helping developers integrate in-app notifications into Filament resources and workflows with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire it up in five minutes. The package is a standard Filament plugin backed by Laravel's database notification channel, so the setup is three commands and one provider line:

composer require iracode-com/filament-notification
php artisan notifications:table && php artisan migrate   # skipped if you already have Laravel notifications
php artisan vendor:publish --tag="filament-notification-config"   # verify tag name in the repo README

Then register the plugin on the panel you actually want the bell on:

// app/Providers/Filament/AdminPanelProvider.php
public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(FilamentNotificationPlugin::make());
}

Where to look first, in this order: the published config/filament-notification.php (polling interval, icon, colors, panel visibility), the repo README (the only source of truth here — there are 2 stars and no docs site, so treat the README and src/ as the spec), and the notifications migration from Laravel core. The bell is just a view over that table, so if you understand what's in it, you understand the package.

First use case. Send yourself a notification and confirm it renders before you build anything else:

use Illuminate\Support\Facades\Notification;
use App\Notifications\WelcomeUser;

auth()->user()->notify(new WelcomeUser());   // via(['database'])

The notification class only needs via() returning ['database'] and a toDatabase($notifiable) returning an array. That array is what the slide-over renders — title, body, icon, color. Get one row on screen, then expand.

Implementation Patterns

Reuse Filament's own sendToDatabase(). You do not need a bespoke notification class to feed this panel. Filament's built-in Notification::make()->title(...)->sendToDatabase($user) writes the exact same rows the bell reads, so existing Filament code paths light up the bell for free. This is the highest-leverage integration point and the first thing to check when someone asks "why doesn't my notification appear?" — it usually wasn't sent to the database channel.

Shape toDatabase() deliberately. Filament reads conventional keys, so return a structured array rather than a string:

public function toDatabase($notifiable): array
{
    return [
        'title' => 'Invoice overdue',
        'body'  => "Invoice #{$this->invoice->number} is 3 days late.",
        'icon'  => 'heroicon-o-exclamation-triangle',
        'color' => 'danger',          // Filament palette name, not hex
        'url'   => route('filament.admin.resources.invoices.edit', $this->invoice),
    ];
}

Audience/broadcast sends. For "notify every admin," chunk the recipient query — User::role('admin')->chunkById(200, fn ($users) => Notification::send($users, new MaintenanceNotice)) — and make the notification ShouldQueue so the request doesn't block. Keep in mind the notification is written under each user's notifiable record, so a 5,000-user broadcast is 5,000 rows, not one.

Drive it from domain events. The clean pattern is listener → notification, not controller → notification. OrderShipped event fires, a queued listener calls Notification::send($order->customer, new OrderShippedNotification($order)), the bell badge increments on the next poll. This keeps dispatch out of the request cycle and makes the notifications testable in isolation.

Polling is a config knob, not a feature to tune later. The unread badge refreshes on an interval from the config. On a panel with hundreds of concurrent admins, a 5-second poll is an unread-count query per user per 5 seconds. Start at 30–60 seconds unless the use case genuinely needs instant badge updates, in which case look at broadcasting rather than shrinking the interval.

Testing. Notification::fake() covers dispatch assertions (assertSentTo), and a direct query against notifications covers persistence. For rendering, hit the panel route as a user with a seeded notification and assert the title appears — the slide-over is a Livewire component, so Livewire's assertSee works.

Gotchas and Tips

Morph map drift silently breaks old rows. Laravel stores notifiable_type as the full class name unless you've set a morph map. If you introduce Relation::enforceMorphMap() after notifications already exist, the package's queries miss historical rows. Decide the morph map before you ship, or write a data migration.

Restart queue workers on every deploy. If notification classes are queued, workers hold serialized payloads referencing the old class definition. php artisan queue:restart in the deploy script — this bites most often when you change the toDatabase() array shape and old jobs render with missing keys.

Never serialize models into action payloads. Filament serializes notification actions into the JSON row. Closures and Eloquent models in action configs won't survive the round trip. Use ->url(route(...)) or a route name plus an ID, and resolve the model at click time.

Use Filament color names for color. 'success', 'danger', 'warning', 'info', 'primary' adapt to dark mode; a hardcoded hex will look wrong in one theme and Filament may reject it. Same for icons — heroicon names only.

Mark-read vs dismiss are different operations. Confirm which one the panel's dismiss button maps to before promising users a retention policy. If dismiss deletes, you lose the audit trail; if it only marks read, the table grows unbounded and you'll want a pruned notifications table (Laravel supports $notifiable->notifications()->where('created_at','<', ...)->delete() in a scheduled command).

Multi-panel and tenancy need manual scoping. The plugin registers per-panel, but notifications are not automatically tenant-scoped. If you use Filament tenancy, either filter in your notification queries or key off the notifiable record — otherwise a user switching tenants sees another tenant's alerts in the bell.

Notifications from other packages render, but blandly. Anything writing to the notifications table shows up here — including rows from third-party packages whose payloads lack icon/color. Add a fallback in your view or a Notification::macro if the empty-icon look bothers you.

Pin the exact version and read the diffs. At 2 stars with a single maintainer and changelogs that read "fixed bugs / update user notification," you are the QA function. Constrain to an exact version (1.4.2, not ^1.4), and review the diff before any bump — the last release changed user notification behavior under a patch number, which means a composer update can change what your users see. Keep an upgrade note in your repo's docs/ so the next developer isn't re-deriving this.

Extension points are thin by design. Customization runs through the config file, the toDatabase() payload, and Filament's own view overrides — there's no events API or driver system here. If you outgrow it, the fallback is straightforward: swap the plugin for a custom Livewire bell component reading the same table. That low switching cost is the strongest argument for trying it.

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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle