Skip to content




Hanlde Page Not Found (404) error

When user requests to a non-existing page, 404 error will be returned. We can reponse to users a customized page to notify about the error, and we also can show some search result of what they are looking for.

Last update: 2022-05-07


The 404 page#

Whenever a page is not found in a website, the error 404 is return to the requested users. I need to create this special page to display a short message and guide user to search in this blog.

The 404 page should be created in the overrides folder as it will replace the default 404 pages of Material theme.

TRY THIS 404 Page

Layout and content#

Its layout is based on the main.html, and the content is a message displayed in the center of the page. The disqus comment section is removed. The sidebar should not be visible to display message clearly.

Search suggestion#

I assume that the path of URL contains keywords of what users are looking for. Therefore, after getting the requested URL from window.location.pathname, I will try to open a search form filled with those keywords.

JavaScript is helpful here. The sequence of handling is as below:

  1. Show 404 message and wait for 5 seconds
  2. Open search form
  3. Get URL path name, and spit it into keywords
  4. For each keyword, fill it into input form
  5. Fire events (value changed, element focused) to trigger search engine

Delay using Asynchronous function

Looking up result may take some time to return, therefore, async function is used to wait for the data.

Source code#

overrides\404.html
{% extends "main.html" %}

{% block site_nav %}
{% endblock %}

{% block content %}

{# styles #}
<style>
    .md-typeset .caution * {
        text-align: center;
    }
    .md-typeset .caution h3 {
        border-bottom: none;
    }
</style>

<div class="caution">
    <h1>
        Oops! Something went wrong!
    </h1>
    <h3>
        Please go back to the <a href="{{ config.site_url }}">{{ config.site_name }}</a> homepage,<br>
        or press <kbd>S</kbd> to search on this site.
    </h3>

    <p id="info"> We will open a search for your in <span id="counter">5</span> second(s)!</p>

</div>

<!-- Open search -->
<script>
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }

    function countdown() {
        var i = 4;
        var x = setInterval(function () {
            document.getElementById("counter").textContent = i;
            i--;
            if (i < 0) {
                clearInterval(x);
                document.getElementById("info").style.display = "none";
                searchForUserRequest();
            }
        }, 1000);
    }

    async function searchForUserRequest() {
        document.querySelector("label.md-search__icon.md-icon").click();

        pathname = window.location.pathname;
        requests = pathname.split("/");

        for (var i = requests.length - 1; i > 0; i--) {
            if (await haveSearchResult(requests[i])) {
                break;
            }
        }
    }

    async function haveSearchResult(request) {
        console.log(request);

        document.forms.search.query.value = request;
        var ev = new Event('change');
        document.forms.search.query.dispatchEvent(ev);
        var ev2 = new Event('focus');
        document.forms.search.query.dispatchEvent(ev2);

        await sleep(1000);
        result = document.querySelector("div.md-search-result__meta").textContent;
        if (result == 'No matching documents') {
            return false;
        }
        return true;
    }

    window.onload = countdown;

</script>
{% endblock %}

{% block disqus %}
{% endblock %}

Comments