Lektor Out-of-the-Box Step 3: A Custom 404 Page for Your Site

- August 20, 2018

This is the third blog post in the Lektor Out-of-the-Box: Step-by-Step series. This blog series uses the Lektor static CMS "out-of-the-box" (without any plugins) to build a demo website in a series of steps. Each subsequent step will show a step-by-step increase in functionality.

Step 2 is discussed in the Lektor Out-of-the-Box Step 2 - An HTML Sitemap for Your Site blog post. Step 3 builds on that, so if you haven't already read that post, now might be a good time to do so. This step adds a custom 404 error page to the website. Then it (optionally) adds a DuckDuckGo site search box to the custom 404 error page. The resulting Demo site with a 404 Page is hosted on GitHub Pages.

The instructions and output below are Windows-specific. However, since Lektor is cross-platform, they should be similar on Linux or macOS.

Why You Should Add a Custom 404 Error Page to Your Site

Noone likes receiving a "404 Error" message, or being told that "The requested URL ... was not found on this server." Regularly validating your site's links with the W3C Link Checker can help minimize how often your users see something like this. Checking the Checker's "Check linked documents recursively" checkbox causes it to check all of the links on your entire site. And checking "Summary only" prevents it from listing all of the links it's checked. Instead, it will list only the links which failed its checks in some way.

But even if all of your internal links are correct, if you ever move or delete a page (without redirecting it), any external links to that page will give others a "404 Error". The same will happen if someone accidentally links to, or accidentally types, the wrong URL for your page. That's why your site needs a custom 404 page.

What Should Your Custom 404 Error Page Include?

When looking to add a new feature to this Website, I've found it helpful to see if others have done something similar using Lektor. In addition to the many built-with-Lektor Websites featured in the Lektor Showcase, I came across the blog site of Animesh Bulusu and its source code on GitLab.io. I noticed a couple of things about his custom 404 error page that I wanted to include on my site.

To help users find what they were looking for, his 404 page:

  • Points them to his Sitemap.
  • Tells them how to search his site on Google, DuckDuckGo, or Bing:

No search engine on my site yet. So, if you must search something on my site, you could put the below phrase in google/ddg/bing.

Replace "python" with your search term.

site:animesh.blog "python"

That motivated me to implement a custom DuckDuckGo site search box on my custom 404 page and on my HTML Sitemap as well. In this post, I'll explain how you can add a custom 404 error page to your Lektor site, and then how to (optionally) add a DuckDuckGo site search box to it.

Lektor: Error Pages explains some of the basics of how to do this with Apache, nginx, or lighttpd. I'll explain, step-by-step, how to do this for our basic demo site on GitHub Pages.

Steps to Adding a Custom 404 Error Page:

Step 1. Modify Your Lektor Project File?

When used for a GitHub project Website (See below), the Lektor: Error Pages instructions don't quite work for me, as they're written. They say to add the following line your your \lektor-out-of-the-box-step-by-step.lektorproject file:

url_style = absolute

The resulting project file is:

[project]
name = lektor-out-of-the-box-step-by-step
url_style = absolute

The absolute url_style is supposed to work best for custom 404 error pages. It's what I've been using here on this site (where you're reading this). And it does work fine here on this site.

However, it doesn't work as well on a GitHub Pages project Website like https://russelljqa.github.io/lektor-out-of-the-box-step-03. Using the absolute url_style, links try to take you one level up to pages on https://russelljqa.github.io (my GitHub Pages user Website) rather than to pages on https://russelljqa.github.io/lektor-out-of-the-box-step-03 (the GitHub Pages project Website). You can see this problem yourself at https://russelljqa.github.io/lektor-404-demo-step3.

This problem seems to be a result of the way GitHub Pages handles project Websites. In some ways, they seem to be treated as lower-level pages on a GitHub Pages user Website, rather than as separate Websites.

So, in the end, I changed my project file back to what it originally had, just:

[project]
name = lektor-out-of-the-box-step-by-step

That defaults the url_style to relative (the default). And it works fine for me on my GitHub Pages project Website.

So, I'd recommend you just let url_style default to relative as well.

Step 2. Create a 404 Contents File

Add the following content\404.html\contents.lr file:

_template: 404.html
---
_model: page
---
_discoverable: no

That tells Lektor to use the \models\page.ini model file and the \templates\404.html template file for your custom 404 error page. And _discoverable: no will keep your custom 404 page out of your HTML sitemap (and your XML sitemap, if you have one).

Step 3. Create a 404 Template File

Add the following templates\404.html file:

{% extends 'layout.html' %}
{% block title %}Page not found{% endblock %}
<meta name="robots" content="noindex, nofollow">
{% block body %}

    <h2>I'm sorry. I'm having a hard time finding that page.</h2>

    <p>
        You may be able to find what you're looking for using my
        <a href='/sitemap/'>Sitemap</a>.
    </p>

{% endblock %}

The first line of this file tells Lektor that this template is an extension of your \templates\layout.html file. The second line gives your page a title of "Page not found". Having a page title is important both for accessibility and for SEO. The third line tells Web (search engine) robots not to index your custom 404 error page, and not to follow any links it contains in order to index them. The rest of this file is beginning contents for your custom 404 error page.

Then build your site with Lektor. Here's what it should look like.

You might want to add some information on how to contact you. For example, the template for my site's custom 404 error page has:

<p>
    If you need some help, or would like to let me know how you got here,
    please <a href='{{ '/contact/'|url }}#contact-form'>contact me</a>.
</p>

That links people to my site's contact page.

Step 4. Add an .htaccess File to Activate Your Error Page

The Lektor documentation doesn't explain how to activate your error page on a GitHub pages site. And the GitHub documentation assumes you're using Jekyll rather than Lektor. But I tried what the Lektor documentation says to do for an Apache server. I added an \assets\.htaccess file:

ErrorDocument 404 /404.html

That seems to work fine both on my GitHub Pages project Website and here on this site.

Step 5 (Optional). Add a DuckDuckGo Site Search Box

Add it to your \templates\404.html file:

  1. Go to DuckDuckGo Search Box builder.
  2. Adjust the settings on that page to customize your search box. The settings I adjusted are:
    1. Entered the URL of this demo website ("https://russelljqa.github.io/lektor-out-of-the-box-step-03/" [without the quotes]) in the "Site search:" input text box.
    2. Replaced "Search DuckDuckGo" with "Search this site" in the "Prefill:" input text box
  3. Copy the resulting <iframe> code into your \templates\404.html file. Place it just before the end block at the end of the file. Here's the code I copied:
            <iframe src="https://duckduckgo.com/search.html?site=https://russelljqa.github.io/lektor-out-of-the-box-step-03/&prefill=Search this site" style="overflow:hidden;margin:0;padding:0;width:408px;height:40px;" frameborder="0"></iframe>
        
  4. Put some appropriate HTML code before the search box, to clarify what it's there for. Here's the code I used:
            <h2 tabindex='0'>Search this site</h2>
        
           
            <p>Haven't found what you're looking for? Then search this site below, using DuckDuckGo — "the search engine that doesn't track you".</p>
        
    The tabindex = '0' puts the added <h2> heading into the tab order. That can be helpful for users who tab through the webpage instead of using a mouse.

Then rebuild your site with Lektor. Here's what it should look like:

DuckDuckGo Site Search Box Added To the Custom 404 Error Page