Create a very Cool 404/503 Error Page with Laravel!
Tags: php, laravel, javascript, webdev
Published: 2021-08-30 14:47:46

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.
{% codepen https://codepen.io/code2rithik/pen/LYxewMN %}

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.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bqz3qrfpfahl8ezi3exf.png)

# Sample Code
## Blade Files
Base：**resources/views/errors/layouts/base.blade.php**
```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**
```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
```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
```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
```
![ezgif-2-ecaa0e6b7f99](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xig00re5f4ml2kjg0l3n.gif)

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](https://twitter.com/ichii731) if you like :D