Reader Stacks

Showing Success and Error Flash Messages in Laravel

session()->flash() for a message that survives exactly one redirect, and why it disappears if you check for it before the redirect actually happens.

Showing Success and Error Flash Messages in Laravel

A flash message is data stored in the session for exactly one subsequent request — the classic "your changes have been saved" banner that shows once after a redirect, then disappears on the next page load.

Setting a flash message

public function store(Request $request)
{
    Order::create($request->validated());

    return redirect()->route('orders.index')->with('success', 'Order created successfully.');
}

->with() on a redirect response is shorthand for flashing that key to the session — it only persists for the next request, then it's gone.

Displaying it in a Blade layout

@if (session('success'))
    <div class="alert alert-success">{{ session('success') }}</div>
@endif

@if (session('error'))
    <div class="alert alert-danger">{{ session('error') }}</div>
@endif

Putting this check in a shared layout (rather than every individual view) means any controller can flash success or error and have it show up automatically after the next redirect, without each view needing its own display logic.

Why it "disappears" — and why that's the point

Flash data is automatically removed from the session after being read on the very next request — this is the intended behavior, not a bug. If you need a message to survive across more than one request, session()->flash() is the wrong tool; store it as regular (non-flash) session data and clear it yourself when appropriate instead.

Multiple message types at once

return back()->withErrors(['email' => 'That email is already taken.']);
// vs
return back()->with('error', 'Something went wrong.');

withErrors() is specifically for validation-style field errors (available via $errors in Blade) — a general one-off flash message like "Something went wrong" is a different, simpler mechanism and shouldn't be mixed into the validation error bag.