DEV Community

IchiiP
IchiiP

Posted on • Updated on

Create a very Cool 404/503 Error Page with Laravel!

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 helperasset('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.
Alt Text

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>
Enter fullscreen mode Exit fullscreen mode

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.")
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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;
    }
});
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

ezgif-2-ecaa0e6b7f99

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

Discussion (0)