Mensajes flash
Los mensajes flash son notificaciones temporales que se muestran al usuario después de una acción: "Usuario creado correctamente", "Error al guardar", etc. Laravel almacena estos mensajes en la sesión y los elimina automáticamente tras mostrarlos.
¿Qué son los mensajes flash?
Los mensajes flash son datos que se guardan en la sesión solo para la siguiente petición. Son perfectos para:
- Confirmar que una acción se completó correctamente
- Mostrar errores que no son de validación
- Informar al usuario de cambios importantes
A diferencia de los errores de validación (que vimos en lecciones anteriores), los mensajes flash son genéricos y los controlas tú completamente.
Enviar mensajes flash
La forma más común es usar el método with() en una
redirección:
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users',
]);
User::create($validated);
return redirect()
->route('users.index')
->with('success', 'Usuario creado correctamente.');
}
}
El método with('clave', 'valor') guarda el mensaje
en la sesión. La clave puede ser cualquier nombre: success,
error, info, warning, etc.
Mostrar mensajes en Blade
Laravel ofrece la directiva @session para mostrar
mensajes flash de forma elegante. Si el valor existe, se muestra
el contenido y puedes usar $value para acceder al mensaje:
{{-- resources/views/users/index.blade.php --}}
@session('success')
<div class="alert alert-success">
{{ $value }}
</div>
@endsession
@session('error')
<div class="alert alert-danger">
{{ $value }}
</div>
@endsession
{{-- Resto de la vista --}}
También puedes usar la sintaxis tradicional con
@if y el helper session():
@if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
Los mensajes flash solo existen para la siguiente petición. Si el usuario recarga la página, el mensaje desaparece automáticamente.
Tipos de mensajes comunes
Es buena práctica usar nombres consistentes para los tipos de mensaje:
<?php
// Éxito - acción completada correctamente
return redirect()->route('users.index')
->with('success', 'Usuario creado correctamente.');
// Error - algo salió mal
return redirect()->route('users.index')
->with('error', 'No se pudo eliminar el usuario.');
// Información - mensaje neutral
return redirect()->route('dashboard')
->with('info', 'Tu sesión se cerrará en 5 minutos.');
// Advertencia - precaución
return redirect()->route('settings.index')
->with('warning', 'Algunos cambios requieren reiniciar.');
Múltiples mensajes flash
Puedes encadenar varios mensajes con with():
<?php
return redirect()->route('users.index')
->with('success', 'Usuario creado.')
->with('info', 'Se ha enviado un email de bienvenida.');
O usar un array:
<?php
return redirect()->route('users.index')->with([
'success' => 'Usuario creado.',
'info' => 'Se ha enviado un email de bienvenida.',
]);
Usando el facade Session
También puedes usar directamente el facade Session
para más control:
<?php
use Illuminate\Support\Facades\Session;
// Guardar mensaje flash
Session::flash('success', 'Operación completada.');
// También disponible con el helper session()
session()->flash('success', 'Operación completada.');
// Mantener mensajes flash para otra petición más
Session::reflash();
// Mantener solo ciertos mensajes
Session::keep(['success', 'info']);
Componente reutilizable para alertas
Para evitar repetir código, crea un componente Blade que muestre todas las alertas:
{{-- resources/views/components/alerts.blade.php --}}
@session('success')
<div class="alert alert-success">{{ $value }}</div>
@endsession
@session('error')
<div class="alert alert-danger">{{ $value }}</div>
@endsession
@session('warning')
<div class="alert alert-warning">{{ $value }}</div>
@endsession
@session('info')
<div class="alert alert-info">{{ $value }}</div>
@endsession
Luego inclúyelo en tu layout principal:
{{-- resources/views/layouts/app.blade.php --}}
<body>
<x-alerts />
<main>
{{ $slot }}
</main>
</body>
Ejemplo completo: CRUD con mensajes
Veamos un controlador CRUD completo con mensajes flash:
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\Article;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class ArticleController extends Controller
{
public function index(): View
{
$articles = Article::latest()->paginate(10);
return view('articles.index', compact('articles'));
}
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'body' => 'required|string',
]);
Article::create($validated);
return redirect()
->route('articles.index')
->with('success', 'Artículo creado correctamente.');
}
public function update(Request $request, Article $article): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
'body' => 'required|string',
]);
$article->update($validated);
return redirect()
->route('articles.index')
->with('success', 'Artículo actualizado correctamente.');
}
public function destroy(Article $article): RedirectResponse
{
$article->delete();
return redirect()
->route('articles.index')
->with('success', 'Artículo eliminado correctamente.');
}
}
Mensajes flash con datos adicionales
A veces necesitas pasar más que un simple texto. Puedes guardar arrays u objetos:
<?php
// Guardar un array con tipo y mensaje
return redirect()->route('orders.index')->with('notification', [
'type' => 'success',
'title' => 'Pedido confirmado',
'message' => 'Tu pedido #' . $order->id . ' ha sido procesado.',
]);
@if(session('notification'))
@php $notification = session('notification'); @endphp
<div class="alert alert-{{ $notification['type'] }}">
<strong>{{ $notification['title'] }}</strong>
<p>{{ $notification['message'] }}</p>
</div>
@endif
Redirección con errores personalizados
El método withErrors() permite enviar errores que
se muestran igual que los de validación:
<?php
public function processPayment(Request $request): RedirectResponse
{
// Simular error de pago externo
$paymentSuccessful = false;
if (! $paymentSuccessful) {
return redirect()
->back()
->withErrors(['payment' => 'El pago no pudo procesarse.'])
->withInput();
}
return redirect()->route('orders.success');
}
@error('payment')
<div class="alert alert-danger">{{ $message }}</div>
@enderror
Resumen
- Los mensajes flash viven solo una petición
redirect()->with('clave', 'mensaje')envía un mensaje@session('clave')muestra el mensaje con$value- También puedes usar
session('clave')con@if - Usa nombres consistentes:
success,error,info,warning - Crea un componente reutilizable para mostrar alertas
Session::flash()permite más controlSession::reflash()mantiene los mensajes una petición máswithErrors()envía errores personalizados
Ejercicios
Ejercicio 1: Mensajes en un controlador de tareas
Crea un controlador TaskController con métodos
store, update y destroy.
Cada método debe redirigir a tasks.index con un
mensaje de éxito apropiado.
Ver solución
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use App\Models\Task;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class TaskController extends Controller
{
public function store(Request $request): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
]);
Task::create($validated);
return redirect()
->route('tasks.index')
->with('success', 'Tarea creada correctamente.');
}
public function update(Request $request, Task $task): RedirectResponse
{
$validated = $request->validate([
'title' => 'required|string|max:255',
]);
$task->update($validated);
return redirect()
->route('tasks.index')
->with('success', 'Tarea actualizada correctamente.');
}
public function destroy(Task $task): RedirectResponse
{
$task->delete();
return redirect()
->route('tasks.index')
->with('success', 'Tarea eliminada correctamente.');
}
}
Ejercicio 2: Componente de alertas con iconos
Crea un componente Blade x-alert que reciba un
parámetro type (success, error, warning, info) y
muestre un icono diferente según el tipo. El mensaje se pasa
como slot.
Ver solución
{{-- resources/views/components/alert.blade.php --}}
@props(['type' => 'info'])
@php
$icons = [
'success' => '✓',
'error' => '✕',
'warning' => '⚠',
'info' => 'ℹ',
];
$icon = $icons[$type] ?? $icons['info'];
@endphp
<div {{ $attributes->merge(['class' => 'alert alert-' . $type]) }}>
<span class="alert-icon">{{ $icon }}</span>
<span class="alert-message">{{ $slot }}</span>
</div>
{{-- Uso: --}}
{{-- <x-alert type="success">Usuario creado.</x-alert> --}}
Ejercicio 3: Múltiples mensajes flash
En un controlador, después de procesar una compra, envía dos mensajes flash: uno de éxito con "Compra realizada" y otro de información con "Recibirás un email de confirmación". Luego escribe el código Blade para mostrar ambos mensajes.
Ver solución
<?php
// En el controlador
public function completePurchase(Request $request): RedirectResponse
{
// Procesar la compra...
return redirect()
->route('orders.index')
->with('success', 'Compra realizada correctamente.')
->with('info', 'Recibirás un email de confirmación.');
}
{{-- En la vista --}}
@if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
@endif
@if(session('info'))
<div class="alert alert-info">
{{ session('info') }}
</div>
@endif
¿Has encontrado un error o tienes una sugerencia para mejorar esta lección?
Escríbenos¿Te está gustando el curso?
Tenemos cursos premium con proyectos reales, soporte personalizado y certificado.
Descubrir cursos premium