· yebor974 · Advanced Techniques, Tutorials

Keep public FilamentPHP notifications visible until user closes

Learn how to persist Filament notifications in Laravel so they stay visible across page navigation until the user manually closes them.

Keep public FilamentPHP notifications visible until user closes picture

In a previous tutorial about Managing public alerts with Filament Notifications in Laravel, I explained how to display public alerts using Filament notifications in Laravel, via middleware.

However, the notifications disappeared as soon as the user navigated to another page — even if the alert wasn’t closed.

This follow-up improves that experience: notifications now stay visible across page navigation and are only removed when the user manually closes them.

What we want to achieve

  • Display up to 3 public notifications using Filament
  • Keep them visible on every page until manually dismissed
  • Save dismissed notification IDs in the session to avoid redisplaying

Create a custom Livewire component

We extend the built-in Filament\Notifications\Livewire\Notifications component to hook into the close event and store dismissed alert IDs in the session.

namespace App\Livewire;

use Filament\Notifications\Livewire\Notifications;
use Livewire\Attributes\On;

class CustomNotifications extends Notifications
{
    #[On('notificationClosed')]
    public function removeNotification(string $id): void
    {
        parent::removeNotification($id);

        // Store the closed alert ID in the session
        session()->push('read_alerts.id', $id);
    }
}

You don’t need to override the view — we use the default Filament notifications view.

Update the Alert Middleware

We modify the middleware that shows public alerts:

  • Remove the alert ID from session only on close (not when shown)
  • Set a fixed ID for each notification, matching the database id for example
  • Filter out already dismissed alerts
use Closure;
use Illuminate\Http\Request;
use Filament\Notifications\Notification;
use App\Models\Alert;

class AlertMiddleware
{
    public function handle(Request $request, Closure $next)
    {
        $readIds = session()->get('read_alerts.id', []);

        $alertQuery = Alert::query()
            ->published()
            ->whereNotIn('id', $readIds)
            ->limit(3);

        foreach ($alertQuery->get() as $alert) {
            Notification::make()
                ->id($alert->id)
                ->icon($alert->type->getIcon())
                ->iconColor($alert->type->getColor())
                ->color($alert->type->getColor())
                ->title($alert->title)
                ->body($alert->message)
                ->send();

            // Removed: session()->push('read_alerts.id', $alert->id);
        }

        return $next($request);
    }
}

By default, Filament defines a random UUID as id.

Use the custom Component in your layout

Replace the default notifications Livewire component with your new one in your public layout.

{{-- Replace this --}}
@livewire('notifications')

{{-- With this --}}
@livewire('custom-notifications')

Final result

  • Public alerts now stay visible across pages
  • They disappear only when the user closes them
  • Once dismissed, they won’t reappear in the session

This provides a much better user experience for important alerts like legal notices, feature updates, or system warnings.

Bonus Tips

  • You can also persist read alert IDs in the database if needed (for logged-in users).
  • Customize the appearance of the notifications via Tailwind or Filament’s theming options.

Let me know what you build!

Did this help you improve your public alert system? If so, please like and share!

Thanks to @yagrasdemonde for the inspiration behind this tutorial!

Happy coding!

Avatar of yebor974
yebor974
Freelance - French IT Engineer passionate about Laravel and Filament PHP, creating innovative solutions to simplify web development.
React
Share post

Stay ahead in the Filament Mastery adventure

Join our community of Filament PHP enthusiasts! Get exclusive tips, tutorials, and updates delivered straight to your inbox.