Certainly! Here’s a clear answer for your question based on current best practices for handling Flux (or Livewire-powered) toast notifications via "classic" controller routes rather than Livewire actions.
TL;DR
You are not reinventing the wheel; your approach using session flash and adding a script block for the toast is correct if you want the toast to persist through a redirect after a POST. Livewire and Laravel Starter Kits do not generally ship with “out of the box” support for triggering JS-based toasts after HTTP (controller) redirects — that’s what Livewire events/components are for. Your solution is idiomatic for controller-to-view scenarios.
Detailed Solution / Best Practice
1. Flashing Message to the Session (Controller/Route)
This is correct:
Route::post('/lab', function () {
session()->flash('flux-toast', [
'text' => 'Record saved successfully!',
'variant' => 'success',
]);
return redirect()->back();
})->name('lab')->middleware('auth');
2. Showing the Toast (Blade)
Since Blade cannot push a Livewire event directly from a non-Livewire route, the correct way is to check for the session variable and then output a JS script (as you did). Your code is "standard" for such a scenario, and looks like this:
@if(session()->has('flux-toast'))
@php $toast = session('flux-toast'); @endphp
<script>
function showToast() {
Flux.toast({
text: @js($toast['text']),
variant: @js($toast['variant'] ?? 'success'),
});
}
if (document.readyState === 'complete') {
showToast();
} else {
document.addEventListener('DOMContentLoaded', showToast, { once: true });
}
document.addEventListener('livewire:navigated', showToast, { once: true });
</script>
@endif
Improvements:
- Use
@js()(Laravel 10+) for safe JS escaping. - Using
{ once: true }prevents multiple firings. - You could also emit a Livewire event if you want, but in this scenario, that would not give you much more.
3. Why isn’t this "out of the box"?
The starter kits (Jetstream, Breeze) and many packages expect Livewire interactions for this kind of thing. They may not have a generic Blade-to-JS toast message (because generally server-side POST + redirect is not expected to fire a JS toast — only in fully client-side/SPA/Livewire interactions or with inertia.js).
4. Alternative
If you want to DRY this up, you can extract this into a Blade component or include for all pages:
resources/views/components/flux-toast-session.blade.php:
@if(session()->has('flux-toast'))
@php $toast = session('flux-toast'); @endphp
<script>
function showToast() {
Flux.toast({
text: @js($toast['text']),
variant: @js($toast['variant'] ?? 'success'),
});
}
if (document.readyState === 'complete') {
showToast();
} else {
document.addEventListener('DOMContentLoaded', showToast, { once: true });
}
document.addEventListener('livewire:navigated', showToast, { once: true });
</script>
@endif
And then just put this near the end of your layout:
<x-flux-toast-session />
Summary
You are doing it right.
Your way is the Laravel-advised approach for classic controller POST/redirect workflows when working with JavaScript toast notifications. There’s no "missing piece" in the starter kits — they just expect Livewire or SPA approaches for this kind of real-time feedback.
If you want, you can make it a reusable Blade component (see above), but otherwise — your solution is both correct and idiomatic!
Happy coding, and welcome to the Laravel + Livewire world!