Introducción
Laravel, uno de los frameworks PHP más populares, ofrece un sistema robusto para manejar errores HTTP. Personalizar estas páginas de error no solo mejora la experiencia del usuario, sino que también mantiene la coherencia visual con el resto de tu aplicación. En este artículo, exploraremos diferentes formas de personalizar las páginas de error en Laravel utilizando Blade.
Configuración Básica de Páginas de Error
Por defecto, Laravel muestra páginas de error genéricas para los diferentes códigos de estado HTTP. Sin embargo, puedes personalizar fácilmente estas vistas.
¡Importante! Las páginas de error personalizadas solo se mostrarán cuando el modo debug no esté habilitado (
APP_DEBUG=falseen tu archivo .env). Cuando el modo debug está activado, Laravel muestra su propia página de error con información detallada para ayudarte en la depuración.
Creando Páginas de Error Personalizadas
Para personalizar una página de error específica, simplemente crea un archivo Blade correspondiente en el directorio resources/views/errors/. El nombre del archivo debe coincidir con el código de estado HTTP:
resources/views/errors/404.blade.php
resources/views/errors/500.blade.php
resources/views/errors/403.blade.phpAccediendo a la Información del Error
Cuando se produce un error, Laravel pasa una instancia de HttpException a la vista como una variable $exception. Puedes utilizar esta variable para mostrar información sobre el error:
<div class="error-container">
<h1>Error {{ $exception->getStatusCode() }}</h1>
<h2>{{ $exception->getMessage() }}</h2>
</div>Publicando las Plantillas por Defecto
Laravel incluye plantillas de error predeterminadas que puedes publicar y modificar según tus necesidades. Para hacerlo, utiliza el comando Artisan:
php artisan vendor:publish --tag=laravel-errorsEste comando copiará todas las plantillas de error predeterminadas a tu directorio resources/views/errors/, permitiéndote personalizarlas sin partir de cero.
Layouts Disponibles al Publicar las Vistas de Error
Al publicar las vistas de error, Laravel incluye dos layouts diferentes que puedes utilizar como base:
1. Layout Minimal (errors::minimal)
Este es el layout predeterminado utilizado por las páginas de error. Proporciona un diseño sencillo con un código de error y un mensaje breve:
@extends('errors::minimal')
@section('title', __('Payment Required'))
@section('code', '402')
@section('message', __('Payment Required'))El layout minimal incluye estilos Tailwind CSS y muestra el código de error junto al mensaje en un diseño limpio.
2. Layout Completo (errors::layout)
Laravel también proporciona un layout alternativo con un diseño centrado:
@extends('errors::layout')
@section('title', __('Page Expired'))
@section('message', __('Page Expired'))Este layout tiene un estilo más simple y solo requiere que definas las secciones title y message. El mensaje se muestra en el centro de la pantalla con un tamaño de fuente mayor.
Puedes elegir el layout que mejor se adapte a tus necesidades, o crear el tuyo propio extendiendo alguno de estos.
Páginas de Error Fallback
Para manejar múltiples códigos de error con una sola plantilla, puedes crear páginas de error "fallback". Estas vistas se utilizarán cuando no exista una página específica para el código de estado que se ha producido.
Errores de Cliente (4xx)
Para todos los errores de cliente (400-499), crea un archivo 4xx.blade.php:
resources/views/errors/4xx.blade.phpErrores de Servidor (5xx)
Para todos los errores de servidor (500-599), crea un archivo 5xx.blade.php:
resources/views/errors/5xx.blade.phpEs importante mencionar que estas páginas fallback no afectarán a los errores 404, 500 y 503, ya que Laravel tiene páginas dedicadas para estos códigos. Para personalizar estos errores específicos, debes crear vistas individuales para cada uno.
Integrando con tu Diseño
Para mantener la coherencia visual en toda tu aplicación, es recomendable que tus páginas de error extiendan la misma plantilla que el resto de tu sitio:
@extends('layouts.app')
@section('content')
<div class="error-container">
<h1>Error {{ $exception->getStatusCode() }}</h1>
<p>{{ $exception->getMessage() ?: 'Lo sentimos, ha ocurrido un error.' }}</p>
<a href="{{ url('/') }}" class="btn btn-primary">Volver al inicio</a>
</div>
@endsectionPersonalizando los Layouts Predeterminados
También puedes optar por personalizar los layouts predeterminados de Laravel. Después de publicar las vistas, encontrarás los archivos minimal.blade.php y layout.blade.php en el directorio resources/views/errors/. Puedes modificar estos archivos para adaptar el diseño y el estilo según tus necesidades.
Ejemplo de Personalización del Layout Minimal
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<!-- Incluir tus propios estilos o frameworks CSS -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<style>
/* Estilos personalizados para las páginas de error */
.error-container {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
background-color: #f8fafc;
}
.error-content {
padding: 2rem;
background-color: white;
border-radius: 0.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
text-align: center;
max-width: 32rem;
}
.error-code {
font-size: 3rem;
font-weight: bold;
color: #ef4444;
margin-bottom: 1rem;
}
.error-message {
font-size: 1.5rem;
color: #4b5563;
margin-bottom: 1.5rem;
}
.home-button {
display: inline-block;
padding: 0.5rem 1rem;
background-color: #3b82f6;
color: white;
border-radius: 0.25rem;
text-decoration: none;
transition: background-color 0.2s;
}
.home-button:hover {
background-color: #2563eb;
}
</style>
</head>
<body>
<div class="error-container">
<div class="error-content">
<div class="error-code">@yield('code')</div>
<div class="error-message">@yield('message')</div>
<a href="{{ url('/') }}" class="home-button">Volver al inicio</a>
</div>
</div>
<!-- Incluir tus propios scripts si es necesario -->
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>Ejemplo de Personalización Avanzada
Veamos un ejemplo más completo que incluye estilos personalizados y un diseño responsive utilizando nuestro propio layout:
@extends('layouts.error')
@section('content')
<div class="flex items-center justify-center min-h-screen bg-gray-100">
<div class="max-w-md w-full p-6 bg-white rounded-lg shadow-lg">
<div class="text-center">
<h1 class="text-4xl font-bold text-red-500">{{ $exception->getStatusCode() }}</h1>
<h2 class="mt-4 text-xl font-semibold">{{ $exception->getMessage() ?: 'Ha ocurrido un error inesperado' }}</h2>
<p class="mt-3 text-gray-600">
@if($exception->getStatusCode() == 404)
No pudimos encontrar la página que estabas buscando.
@elseif($exception->getStatusCode() == 403)
No tienes permisos para acceder a esta página.
@else
Algo salió mal. Por favor, inténtalo de nuevo más tarde.
@endif
</p>
<div class="mt-6">
<a href="{{ url('/') }}" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">
Volver al inicio
</a>
</div>
</div>
</div>
</div>
@endsectionPersonalizando Errores Específicos
Página 404 (Not Found) con Layout Minimal
@extends('errors::minimal')
@section('title', __('Página no encontrada'))
@section('code', '404')
@section('message', __('La página que buscas no existe'))Página 500 (Error del Servidor) con Layout Completo
@extends('errors::layout')
@section('title', __('Error del servidor'))
@section('message', __('¡Ups! Algo salió mal en nuestro servidor.'))Página 403 (Prohibido) con Layout Personalizado
@extends('layouts.app')
@section('content')
<div class="error-container text-center">
<img src="{{ asset('images/403.svg') }}" alt="Acceso prohibido" class="max-w-sm mx-auto">
<h1 class="text-4xl font-bold mt-6">¡Acceso prohibido!</h1>
<p class="mt-3">Lo sentimos, no tienes permisos para acceder a este recurso.</p>
<a href="{{ url('/') }}" class="btn btn-primary mt-4">Volver al inicio</a>
</div>
@endsectionProbando tus Páginas de Error
Para probar tus páginas de error personalizadas, puedes utilizar la función abort() en una ruta de prueba:
<?php
Route::get('/test-404', function () {
abort(404);
});
Route::get('/test-500', function () {
abort(500);
});
Route::get('/test-403', function () {
abort(403, 'No tienes acceso a esta sección');
});Consejo para pruebas: Para ver tus páginas de error personalizadas durante el desarrollo, puedes temporalmente establecer
APP_DEBUG=falseen tu archivo .env mientras realizas las pruebas. No olvides volver a activarlo cuando termines para seguir viendo los mensajes detallados de error durante el desarrollo.
Configurando el Modo de Depuración
La visualización de las páginas de error personalizadas depende de la configuración de depuración en tu aplicación Laravel. Aquí hay algunas consideraciones importantes:
En Desarrollo
Durante el desarrollo, normalmente querrás mantener el modo de depuración activado:
APP_DEBUG=trueCon esta configuración, Laravel mostrará páginas de error detalladas con información sobre la excepción, rastreo de la pila y sugerencias de depuración, en lugar de tus páginas de error personalizadas.
En Producción
En un entorno de producción, siempre debes tener el modo de depuración desactivado:
APP_DEBUG=falseCon esta configuración, Laravel mostrará tus páginas de error personalizadas, ocultando los detalles técnicos a los usuarios finales, lo que es esencial tanto para la seguridad como para la experiencia del usuario.
Conclusión
Personalizar las páginas de error en Laravel es un proceso sencillo pero que puede mejorar significativamente la experiencia del usuario en tu aplicación. Al utilizar el sistema de vistas Blade y la información proporcionada por la excepción, puedes crear páginas de error que sean coherentes con el resto de tu aplicación y proporcionen información útil a tus usuarios.
Laravel ofrece una gran flexibilidad al proporcionar diferentes layouts predeterminados y la capacidad de crear tus propios diseños. Ya sea que prefieras utilizar los layouts incluidos o crear uno completamente personalizado, lo importante es mantener una experiencia de usuario consistente incluso cuando ocurren errores.
Recuerda que estas páginas personalizadas solo se mostrarán cuando el modo de depuración esté desactivado, lo que es el comportamiento adecuado en entornos de producción. Esta separación te permite disfrutar de información detallada durante el desarrollo mientras ofreces una experiencia pulida a los usuarios finales.
Curso Laravel 12
Completo 2026
El único curso 100% actualizado que incluye Laravel 12, Livewire 3, Vue 3, React 19 e Inertia 2. Aprende con proyectos reales y las últimas funcionalidades.
star Incluido en cualquier suscripción