spatie/laravel-flash
Lightweight Laravel package for flashing a single message to the next request via session. Use flash('Message', 'optional-class') in controllers and read flash()->message and flash()->class in your Blade views to display and style it.
Install with composer require spatie/laravel-flash, then immediately start using it in controllers to set one-time messages before redirects. In any controller method handling form submissions or actions where feedback is needed:
public function update(Request $request)
{
// ... validation and saving logic ...
flash('Profile updated successfully!', 'alert-success');
return back();
}
Then in your Blade layout (e.g., layouts/app.blade.php), render the message near the top of the page:
@if (flash()->message)
<div class="{{ flash()->class }}">
{{ flash()->message }}
</div>
@endif
The first use case is typically displaying success or error messages after form submissions—this package shines because it's minimalist, requires no configuration, and integrates cleanly with Laravel’s session system.
levels(): Register standard flash levels in a service provider (e.g., AppServiceProvider or custom FlashServiceProvider) to avoid repeating class names:\Spatie\Flash\Flash::levels([
'success' => 'alert alert-success',
'error' => 'alert alert-danger',
'warning' => 'alert alert-warning',
]);
Then use in controllers:
flash()->success('User created');
flash()->error('Failed to delete record');
message, class, and level properties in Blade: Always use all three for context-aware UI:@if (flash()->message)
<div x-data="{ show: true }"
x-show="show"
:class="{
'bg-green-100 text-green-800': flash().level === 'success',
'bg-red-100 text-red-800': flash().level === 'error',
}"
class="p-4 rounded mb-4">
{{ flash()->message }}
<button @click="show = false" type="button" class="ml-auto">×</button>
</div>
@endif
\Spatie\Flash\Flash::macro('toast', function (string $message, string $level = 'info') {
$this->flashMessage(new \Spatie\Flash\Message($message, 'toast toast-'.$level, $level));
});
Then call flash()->toast('Changes saved', 'success').
flash()->class directly but always default to avoid empty classes:<div @class(['flash-message', flash()->class => flash()->class])>
{{ flash()->message }}
</div>
Only one flash message at a time: The package deliberately supports a single message. Don’t expect to queue multiple messages—this is a feature, not a bug, and it avoids complexity. If you need multiple messages, consider [laracasts/flash] instead.
Casing matters for levels keys: Ensure consistency when using levels() and flash()->level. flash('OK', 'success') and flash()->success('OK') behave identically only if 'success' is registered via levels().
Macro order conflicts: If both a levels() key and a custom macro exist with the same name (e.g., error), the macro will override the level unless both are intentionally aligned. Prefer levels() for simple semantic sugars and macro() only for extra behavior (e.g., toast, JavaScript triggers).
No auto-rendering: You must manually render flash()->message in your Blade templates. There is no auto-flush middleware—this is intentional for simplicity, but newcomers sometimes expect automatic injection.
Session key behavior: The flash message is stored in session under the key flash.old (Laravel’s standard session “old flash” key). Avoid manually interacting with that key elsewhere to prevent overwrite conflicts.
Type hints for IDE support: While flash() returns a dynamic helper object, add docblocks or use /** @var \Spatie\Flash\Flash $flash */ for full IDE autocomplete on custom levels/macros.
Testing tip: Use flash()->message and flash()->class in Feature Tests by asserting session contents:
$response->assertSessionHas('flash.old.message', 'Success!');
composer.json or the changelog if upgrading Laravel major versions—though this package’s minimal API surface makes it remarkably stable across versions.How can I help you explore Laravel packages today?