Custom 404 Pages and Hugo

What’s a 404 Page?

It’s the web page that is served when content can’t be found on a website. Effectively the “what you asked for, can’t be found” and 404 is the HTTP error code for this. Hence, the name 404 page.

If you want to customize what is shown when this happens, you will need to set up a custom 404 page.

Setting up custom 404 Page for Hugo

Ensure there is not currently a page named 404 in your layouts directly, if there is either see if its of use or delete it.

You will need to make ether a:

  • An HTML layout page: layouts\404.html
  • Or a content page content/404.md - you will then redirect to this page.

For example to make a custom layout page in layouts\404.html, which will generate a 404.html file in the root directory.

The example below uses parameters from that can be set up in your config.yaml file to make it more data driven if needed.

  # 404 page options
  pageNotFound:
    image: "<path to main image>"
    # option to specify the title of the 404 page
    title: 404 Page Not Found :(
    # option to specify the subtitle of the 404 page
    subtitle: This is not the page you were looking for.
    # option to specify the width of the image in the 404 page
    imageWidth: 500px

This example is uses elements of the hugo-fresh theme and results in a page that looks like this: https://tinyblueplanet.com/404.html

{{- define "main" -}}
{{- $page404    := .Site.Params.pageNotFound }}
{{- $title      := index $page404 "title" }}
{{- $subtitle   := index $page404 "subtitle" }}
{{- $image      := index $page404 "image" }}
<section class="hero is-fullheight is-default is-bold">
  {{/* partial "navbar.html" . */}}
  {{/* partial "navbar-clone.html" . */}}
  <div class="hero-body">
      <div class="container">
        <div class="columns is-vcentered">
          <div class="column is-5 is-offset-1 landing-caption">
            <h1 class="title is-2 is-bold is-spaced">
              {{ $title }}
            </h1>
            {{- with $subtitle -}}
            <h2 class="subtitle is-5 is-muted">
              {{ . }}
            </h2>
            {{- end -}}
          </div>
          <div class="column is-5 is-offset-1">
            <figure class="image">
                {{- $img := resources.Get $image -}}
                <img src="{{- $image | relURL -}}"
                     style="width:{{- .Site.Params.pagNotFound.imageWidth -}}">
            </figure>
          </div>
        </div>
      </div>
    </div>

  {{/* partial "hero-footer.html" . */}}
</section>
{{- end -}}

You may notice that this page when loaded returns a 200 response status code and not a 404 response status code. In most cases you want the response to be a 404 error. For example, https://tinyblueplanet.com/missing-page will show the same 404 error page, but will return the correct error code.

This requires the slighter harder step of setting a redirect on the server hosting your site. There’s lots of help out there for doing this, and generally it’s pretty simple. Basically you need to tell your server that anytime there is a missing document redirect folks to your error page.

404 Redirect with Apache

Modify or create a .htaccess file that setups your redirect. For example:

ErrorDocument 404 /404.html