It’s been over 4 years since I started to use Jekyll and Github pages. I chose Jekyll for a blog because of its simplicity and seemless intergration with Github. I also really wanted to try out Hugo for quite some time. And ever since Cloudflare released their Pages service.

What I use now

For markuta.com I now use Hugo with a theme called PaperMod. Github is still used storage on a private repository (Github pages doesn’t allow private repos for free accounts). And Cloudflare Pages is linked to Github to deploy the website.

Guide

Requirements

To get started you need the following:

  • Hugo and Git software
  • Github account (free)
  • Cloudflare account (free)
  • Domain name (not required but nice to have)

Install Software

You need to make sure Hugo and Git are installed. For Linux: sudo apt install hugo. For macOS via brew: brew install hugo. And for Windows I’d recommend using a WSL.

Github

Create a Repository

Go ahead and log-in into Github and create a new (public or private) repository, then do a git clone to your local device.

Hugo

Create a new Hugo site

Next, navigate to the cloned repo folder on your local machine and type the following Hugo command to create a new site file structure. The --force flag will write to that the directory even if it already exists, otherwise it’ll complain.

cd ~/my-blog
hugo new site . --force

You can also do the previous steps in reverse, make a new hugo site and create a repo.

Choose a Hugo theme

It’s a good time to choose a Hugo theme. Check out: https://themes.gohugo.io/ for a big list.

Most themes are available on Github and can be installed via submodules. For example to install my current theme (PaperMod) go to the root folder of your repository and run the following:

git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
git submodule update --init --recursive

Edit Hugo config

It is important to note that each theme may have its own configuration file which you need to use. In the case of PaperMod theme a sample is provided: config.yml.

A convert toml based config file (snippet) will look something like this:

baseURL = "https://markuta.com/"
title = "Markuta"
paginate = 5
theme = "PaperMod"

enableRobotsTXT = true
buildDrafts = false
buildFuture = false
buildExpired = false
googleAnalytics = "UA-XXXXXX"

[minify]
disableXML = true
minifyOutput = false # Cloudflare Pages has issues when true

[params]
env = "production"
...

Run Hugo site locally

To run the Hugo site locally first navigate to the root of your repository and type:

hugo server -D

A local web server will start listening on http://localhost:1313 and have output similar to:

hugo server -D
Start building sites …
hugo v0.87.0+extended darwin/amd64 BuildDate=unknown

                   | EN
-------------------+------
  Pages            | 132
  Paginator pages  |   6
  Non-page files   |  44
  Static files     |  12
  Processed images |   0
  Aliases          |  53
  Sitemaps         |   1
  Cleaned          |   0

Built in 130 ms

To stop the web server type ctrl+c.

Cloudflare

Create a project

Go and log-in into Cloudflare and select Pages then click on create a new project. You will be asked to link your Github account and asked to select a repository. I tend to only allow Cloudflare permission to a selected few rather than all of the repositories.

Click “Begin setup” to continue.

Set up builds and deployments

Choose a project name which can only contain lowercase letters (a-z), numbers (0-9), dashes. I use Github’s default main as the production branch.

Next configure the Build settings options:

  • For Framework present set: Hugo
  • For Build command choose hugo (will be automatically set)
  • Build output directory choose public (will be automatically set)
  • Skip Root directory
  • Environment variables
    • Add new variable name HUGO_VERSION with 0.87.0

Finally click Save and Deploy.

If everything went fine your site should be deployed and accessible via <project-name>.pages.dev. You can stop here or continue to set up your own domain.

Add custom domains

From the previous section hit continue to project or just navigate to your project from the Pages menu. Under your project is a Custom domains tab and below that is a Set up a custom domain button. Click it and you will be then asked to give a domain name e.g. markuta.com

Since I already use Cloudflare for DNS management it automatically edited settings for me. A CNAME will be set for www.example.com and domain name flattening applied to example.com because CNAME records are not allowed on root/apex domains.

Issues and Solutions

There were some issues along the way but have now been solved.

Cloudflare Pages builds

For some reason Cloudflare Pages kept failing to build the Hugo website. And after hours of researching and rebuilding I found the culprit.

Example of Cloudflare logs below:

...
17:51:34.982	Installing missing commands
17:51:34.982	Verify run directory
17:51:34.982	Executing user command: hugo
17:51:35.019	Start building sites … 
17:51:35.019	hugo v0.87.0-B0C541E4+extended linux/amd64 BuildDate=2021-08-03T10:57:28Z VendorInfo=gohugoio
17:51:35.226	ERROR 2021/08/28 16:51:35 JSON parse error: expected comma character or an array or object ending on line 61 and column 40
17:51:35.226	   12:     {
17:51:35.226	           ^
...

The issue was down to an option in the config.toml file. The theme I chose had a line minifyOutput = true which was is to do with minifying HTML/CSS elements. I just wish Cloudflare would’ve been a little more helpful with their error messages. Changing the option to false the website built successfully.

Running Hugo locally

I tend to run a Hugo site locally before pushing to Github. After doing a git clone of the remote repo on a new device and running hugo server -D the local site failed to load properly.

Example of Hugo logs below:

...
WARN 2021/08/29 02:10:21 found no layout file for "HTML" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/29 02:10:21 found no layout file for "HTML" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/29 02:10:21 found no layout file for "HTML" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/29 02:10:21 found no layout file for "HTML" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.
WARN 2021/08/29 02:10:21 found no layout file for "HTML" for kind "term": You should create a template file which matches Hugo Layouts Lookup Rules for this combination.

                   | EN
-------------------+-----
  Pages            | 53
  Paginator pages  |  0
  Non-page files   | 43
  Static files     | 11
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Built in 67 ms
...

This one was my fault. I had forgotten that the PaperMod theme is a git submodule and I didn’t give the --recurse-submodules flag when cloning the repo. If you’ve already cloned the repo you can still run it manually:

git submodule init
git submodule update