Hi. This time, let's create a cool 404/503... error page with Laravel.
Error page structure in Laravel
Laravel can display the error page just by placing files in the specified directory without adding any special controller. So it's very easy to support.
All you have to do is to add a file like 400.blade.php to resources->view->errors
directory.
In addition, I would like to add base.blade.php to the layout directory to make it a template.
The file tree looks like below.
└─resources
└─views
└─errors
404.blade.php
└─layouts
base.blade.php
Let's make it!
Now let's actually make it using a template etc.
A sample of the completed site has been uploaded to GitHub.
https://github.com/ichii731/php-examples/tree/main/laravel_error-page
Dev Environment
ubuntu20.04 LTS
PHP 7.4.3
Laravel Framework 6.20.26
Template Engine: Blade
404 page template
This time, I changed a part of the template introduced in DEV Commynity and diverted it. The original template CodePen is here.
It's a cool-looking template that counts up numbers and animates them to 404 and 503.
It may look difficult at first glance, but it's a simple configuration using "for" statements in Javascript. We will use this one.
Customize Template
I did the following changes.
- Converted SCSS to CSS
- Changed the file path for loading CSS, JS to be described in the asset helper←
asset('filepath')
. - Created a base blade to handle various errors, and then modified it to switch the display depending on the error content.
The process of changing the text displayed depending on the error implement using @yield("").
After typing the asset element, the file and directory structure looks like below.
Sample Code
Blade Files
Base:resources/views/errors/layouts/base.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@yield('title')</title>
<link rel='stylesheet' href='{{ asset('/css/flexgrid.min.css') }}'>
<link rel="stylesheet" href="{{ asset('/css/style.css') }}">
</head>
<body>
<!-- partial:index.partial.html -->
<div class="container">
<div class="row">
<div class="xs-12 md-6 mx-auto">
<div id="countUp">
<div class="number" data-count="@yield('http-request')">0</div>
<div class="text">@yield('title')</div>
<div class="text">@yield('message')</div>
<div class="text">@yield('detail')</div>
</div>
</div>
</div>
</div>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script src="{{ asset('/js/in-view@0.6.1.js') }}"></script>
<script src="{{ asset('/js/script.js') }}"></script>
</body>
</html>
404 Error:resources/views/errors/404.blade.php
@extends('errors.layouts.base')
@section('http-request', '404')
@section('title', 'Page not found')
@section('message', 'This may not mean anything.')
@section('detail', "I'm probably working on something that has blown up.")
For other problems like 403 forbidden, 500 Internal Server Error, 503 Service Unavailable, etc, just copy and paste the above file and add something like 500.blade.php
.
CSS/JS Assets
StyleSheet:public/css/style.css
@import url('https://fonts.googleapis.com/css?family=Roboto+Mono:300,500');
html,
body {
width: 100%;
height: 100%;
}
body {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/257418/andy-holmes-698828-unsplash.jpg);
background-size: cover;
background-repeat: no-repeat;
min-height: 100vh;
min-width: 100vw;
font-family: "Roboto Mono", "Liberation Mono", Consolas, monospace;
color: rgba(255,255,255,0.87);
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.container,
.container > .row,
.container > .row > div {
height: 100%;
}
#countUp {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
}
#countUp .number {
font-size: 4rem;
font-weight: 500;
}
#countUp .number + .text {
margin: 0 0 1rem;
}
#countUp .text {
font-weight: 300;
text-align: center;
}
Javascript:public/js/script.js
var formatThousandsNoRounding = function(n, dp){
var e = '', s = e+n, l = s.length, b = n < 0 ? 1 : 0,
i = s.lastIndexOf(','), j = i == -1 ? l : i,
r = e, d = s.substr(j+1, dp);
while ( (j-=3) > b ) { r = '.' + s.substr(j, 3) + r; }
return s.substr(0, j + 3) + r +
(dp ? ',' + d + ( d.length < dp ?
('00000').substr(0, dp - d.length):e):e);
};
var hasRun = false;
inView('#countUp').on('enter', function() {
if (hasRun == false) {
$('.number').each(function() {
var $this = $(this),
countTo = $this.attr('data-count');
$({ countNum: $this.text()}).animate({
countNum: countTo
},
{
duration: 500,
easing:'linear',
step: function() {
$this.text(formatThousandsNoRounding(Math.floor(this.countNum)));
},
complete: function() {
$this.text(formatThousandsNoRounding(this.countNum));
}
});
});
hasRun = true;
}
});
Let's try it out
Let's start a simple server with the artisan command. The actual behavior is like below GIF Image.
php artisan serve
Isn't it cool? Please refer to it ...
I'll also post it on the repo on GitHub. Please try it. (GitHub pushes only laravel diff directories / files)
https://github.com/ichii731/php-examples/tree/main/laravel_error-page
Please also check the blog and Twitter@ichii731 if you like :D
Top comments (0)