Create a single page site with Hugo and Bootstrap

15 November 2021 htmlgohugobootstrapmarkdown

What is Hugo

Hugo is a fast and modern static site generator written in Go, and designed to make website creation fun again.

To create a theme in Hugo we will be using Bootstrap 5

Ok, Let’s Go … and install Hugo

On Mac you can use homebrew

brew install hugo

On linux you can use snap

sudo snap install hugo

For Windows or other ways of installing, see https://gohugo.io/getting-started/installing

NOTE: This tutorial is written and tested, using Hugo version v0.89.0 and Bootstrap v5.1.3 on a MacOS

Start creating your website and name it website

hugo new site website
cd website

Now create a new theme called bootstrap

hugo new theme bootstrap

To make use of our new theme, add the following line to the config.toml file:

theme = "bootstrap"

In the themes/bootstrap/archetypes folder, create a new file singlepage.md with the following content:

---
title: "{{ replace .Name "-" " " | title }}"
weight: 0
menu: true
---

Let’s create our sections for the single page website

hugo new singlepage/about.md
hugo new singlepage/services.md
hugo new singlepage/products.md
hugo new singlepage/contact.md

Change the weight attribute for these sections, see the content/singlepage folder
Our sections will be ordered according the weight value, lower weight first.
You can also enter some content to show on our website for these sections:

Edit the file content/singlepage/about.md

---
title: "About"
weight: 1
menu: true
---
Place About content here

Repeat this step and increase the weight value for the remaining sections

Create a content/singlepage/index.md file with the following content:

headless: true

This will create a headless bundle. Pages inside a headless bundle folder will not get published. We will use another way to show them on our single web page.

Go the Bootstrap website and download the compiled css and js files. From the downloaded Bootstrap folder:

  • copy css/bootstrap.min.css and css/bootstrap.min.css.map to the themes/bootstrap/static/css folder
  • copy js/bootstrap.bundle.min.js and js/bootstrap.bundle.min.js.map to the themes/bootstrap/static/js folder

Edit the themes/bootstrap/layouts/index.html file

{{ $headless := .Site.GetPage "/singlepage" }}
{{ $sections := $headless.Resources.ByType "page" }}
<!DOCTYPE html>
<html id="html" class="bg-dark text-white-50" lang="html">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href='{{ "/css/bootstrap.min.css" | relURL }}' rel="stylesheet">
<script src='{{ "/js/bootstrap.bundle.min.js" | relURL }}'></script>
<body id="body" class="bg-dark text-white-50" data-bs-offset="60" data-bs-spy="scroll"
      data-bs-target="#navbar-header" tabindex="0">
<header>
    <nav class="navbar navbar-dark navbar-expand-lg bg-dark fixed-top">
        <div class="container container-fluid">
            <a class="navbar-brand" href="#">Website</a>
            <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar-toggler"
                    aria-controls="navbar-toggler" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbar-toggler">
                <ul class="navbar-nav ms-auto mb-2 mb-lg-0">
                    {{ range where $sections ".Params.menu" "eq" true }}
                    <li class="nav-item">
                        <a class="nav-link text-decoration-none" href="#{{ anchorize .Title }}">{{ .Title }}</a>
                    </li>
                    {{ end }}
                </ul>
            </div>
        </div>
    </nav>
</header>
<div class="container pt-5">
    {{ range $sections }}
    <h2 id="{{ anchorize .Title }}" class="pt-5">{{ .Title }}</h2>
    <div>
        {{ .Content }}
    </div>
    {{ end }}
</div>
<footer>
    <div class="bg-dark small text-white-50 text-center p-3">&copy; {{now.Format "2006"}} by Me</div>
</footer>
</body>
</html>

Our very basic single page website is now ready. Let’s try it out locally:

hugo server

This will start a local webserver. The console will output the url, for example http://localhost:1313. Browse to this url to view your website.

When you are ready to publish your site, run:

hugo

A public folder will be created. Copy this folder to your webserver.

That’s it. Your site is now published.