edvinaskrucas/notification
Edvinaskrucas Notification is a Laravel package for creating, storing, and managing user notifications. It offers database-backed notification feeds, customizable templates, and a simple API for sending notifications to Eloquent models.
Install via Composer:
composer require edvinaskrucas/notification
On Laravel 5.5+ the service provider and Notification facade are auto-discovered. On older versions, register them manually in config/app.php:
'providers' => [
EdvinasKrucas\Notification\NotificationServiceProvider::class,
],
'aliases' => [
'Notification' => EdvinasKrucas\Notification\Facades\Notification::class,
],
Publish the config so you can tune message types, containers, and view templates:
php artisan vendor:publish --provider="EdvinasKrucas\Notification\NotificationServiceProvider"
The first thing to open is config/notification.php. It defines the default types (success, error, info, warning), the container keys, and the Blade templates used by showAll(). Skim the facade (EdvinasKrucas\Notification\Facades\Notification) next — the public surface is small: success(), error(), info(), warning(), add(), get(), all(), and showAll().
First use case — flash a success message after a form submission and render it in your layout:
// app/Http/Controllers/PostController.php
public function store(Request $request)
{
Post::create($request->validated());
Notification::success('Post created successfully.');
return redirect()->route('posts.index');
}
{{-- resources/views/layouts/app.blade.php --}}
<div class="notifications">
{!! Notification::showAll() !!}
</div>
showAll() prints the configured HTML markup for every queued message. That's the whole loop: add in the controller, redirect, render in the layout.
Chain multiple messages in one request. add() returns the container so you can stack several notifications before a redirect:
Notification::success('Saved.')
->warning('Two images failed to upload.')
->error('Slug was auto-generated.');
Render per-type for custom styling. Instead of showAll(), iterate the types yourself and use your own CSS classes:
@foreach (['success', 'error', 'warning', 'info'] as $type)
@foreach (Notification::get($type) as $message)
<div class="alert alert-{{ $type }}">{{ $message }}</div>
@endforeach
@endforeach
Custom types. Register additional types (e.g. notice, tip, bug) in config/notification.php, then use them via Notification::add('notice', 'Read the changelog.'). Keep the config's types array in sync with any Blade loop that renders them.
Pair with validation errors. On failed validation Laravel already flashes $errors; use the package for the friendlier, domain-specific feedback that validation rules can't express:
if ($order->isAlreadyShipped()) {
Notification::warning('Order was already shipped — changes saved as draft.');
}
Use a view partial, not inline markup. Move the showAll() block (or the per-type loop above) into resources/views/partials/notifications.blade.php and @include it in your layout. This keeps a single place to change alert markup and avoids drift between admin and public layouts.
Returning notifications over JSON/AJAX. When you need the browser to render client-side, pull everything out and serialize:
return response()->json([
'message' => 'Saved.',
'notifications' => Notification::all()->toArray(),
]);
If all() gives you message objects rather than plain strings, map over them (->map(fn ($m) => (string) $m)) so the JSON shape stays predictable.
Multiple containers for multiple audiences. If you need independent message queues (e.g. admin panel vs. frontend), use Notification::setContainer('admin') before adding and before rendering. This is the main extension point for anything more than a single global flash bag.
Integrate into a base controller or trait. Wrap common messages ($this->notifySuccess('...')) in a trait so controllers stay readable and the message copy is centralized.
This package is old. Last tagged release is 2017 (Laravel 5.x era). On modern Laravel (9/10/11) verify the package installs cleanly against your PHP constraint; if Composer refuses, either pin an older platform or fork it. The runtime surface is small (session + a facade), so compatibility is usually limited to the service provider/facade registration rather than deep framework APIs — but test before betting a feature on it.
Session driver matters. Notifications are flashed to the session. If you're running the array driver in tests or local dev, they will vanish between the POST and the redirect. Use file, redis, or database when exercising the flow, and assert on the session in feature tests instead of on rendered HTML.
showAll() prints raw HTML. The default templates escape the message body, but as soon as you edit them and switch to {!! $message !!} to allow links or icons, you own the XSS risk. Sanitize or use a strict whitelist before allowing any user-supplied text through.
Render exactly once. Rendered messages are consumed on the following request. If your layout includes the notification partial and a view also calls showAll(), you can get duplicates or empty output depending on ordering. Pick one location per layout.
Config caching. After editing config/notification.php (new types, changed templates), run php artisan config:clear in development — a cached config will silently ignore your changes, and add('notice', ...) will appear to produce nothing if notice isn't in the cached types array.
Debugging. When messages don't appear, inspect the session directly (session()->all() / the flash keys) right after the redirect. If the data is there, the problem is rendering or showAll() templates; if it's missing, the problem is the redirect chain or session driver.
Chaining returns the container, not the response. Don't try return Notification::success(...) from a controller expecting a redirect — call Notification::success(...) first, then return redirect(...) separately.
Extension points to reach for before forking: custom types in config, custom container names via setContainer(), and custom Blade templates referenced from config. Those cover most "I need this to look different" requests without touching vendor code.
How can I help you explore Laravel packages today?