Using Hugo

PUBLISHED ON OCT 8, 2021 - LAST UPDATE OCT 10, 2021 — HUGO, TECH

I’m using Hugo to run this site. It has some documentation, but I found it a bit hit and miss, so here’s a quick how I did it, rather than a how to. Partly for my records, and partly because it might be useful to others.

I have traditionally used big blog platforms like WordPress to run any blogging I’ve done,but, I wanted to use a static site generator this time round and stick to a super-minimal and performant site. I might post more about why and what that means later, but, assuming you have the same kind of requirements and are looking at Hugo. Here we go.

I run a Windows machine with WSL2, so this should work for you if you’re on WSL2 or Linux. Getting set up is mostly just following the Quick Start guide from Hugo, but here there’s more of a “I’m making an actual site” feel to it and a bit of missing context.

Install

Install Brew

Hugo is installed easiest with Brew it seems. Brew is yet another standard way of installing things. Yay. Instructions are on the Brew home page, I just stuck this into a WSL prompt like they said to do:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

That will tell you what it’s going to do, then do it. It’ll prompt you for your password when it runs a sudo command, after checking you have sudo rights. At the final step it will output some commands you need to execute yourself to finish off setting it up in your profile. Awesome. You now have Brew installed as well as apt and all the other ways you already had…

Install Hugo

Now Brew is installed, we use it to install Hugo, this seemed to take ages:

brew install hugo

And then validate it works validate:

michael@DESKTOP-0V8O7JR:~ $ hugo version
hugo v0.88.1+extended linux/amd64 BuildDate=unknown

Init Site

Version Control

I wanted to manage my site with standard cloud based git version control, because I’m a developer at heart. So I set up a new blank repository on BitBucket, as that’s what we use at work, and cloned that locally.

Initialise Hugo Site

Next, I just used Hugo to create a new blank site in that repository

hugo new site personal-site
cd personal-site
git commit -a -m "Hugo new site init"
git push

Add a Theme

Next step is to add a theme, I decided to use the Goa theme as it looked a lot like the base, simple, minimalist site I’d hand cranked before. I forked the repo first, because I want to control where my changes are, and use Goa as a base and make changes to it. Then I added the fork into my Hugo install as a git submodule and added it to the site configuration, still blindly following the Quick Start guide. But that’s fine.

git submodule add https://github.com/mjervis/hugo-goa themes/goa
echo theme = \"goa\" >> config.toml

At this point, I still haven’t started Hugo!

Basic Site Configuration

Next up was to re-configure my site, the base configuration doesn’t include the stuff that the Goa Theme needs to render correctly, and is all out of the box. By default, Hugo uses TOML. Tom’s Obvious Minimal Language. Yes, because with XML, JSON, YAML, INI files etc, what we really needed as techies was another “obvious” and “minimal” mark-up language to deal with. With it’s own set of quirks. Yay.

So I just cribbed all the details from the demo version of the Goa theme, then tweaked to suit my site. I also had a read to see what those settings were doing. Quite nice the way you can define in custom settings for your site, then use them in the templates transparently.

Mark-up Lanaguages

After doing all the config, I got annoyed and used a TOML to JSON to convert my config.toml file contents to JSON and replaced config.toml with config.json. Hugo supports TOML, JSON or YAML. I didn’t want to learn TOML for this site, I’m super comfortable with JSON and YAML, but went for JSON as I probably use that a bit more than YAML at work.

Now my config file is in JSON, the structure makes much more sense to me, with the various parts it controls all separated out in a nice way!

Development vs Production

Hugo has a nice system of configuration files that are environment specific, you can create a config folder in your Hugo site, with a sub-folder per environment that sets overrides. Defaults are production when you do a compile to generate a static site and development when you spin up the local Hugo server, so I created a basic config\development\config.json file with my development environment overrides:

{
    "baseURL": "http://localhost:1313/",
    "builddrafts": true,
    "canonifyurls": false
}

I want drafts in my dev environment and not in production, I’ve tweaked the base URL for the site and told it not to generate absolute links. Simple I think. Might get richer over time. BaseURL in my main config.json file is set to my domain, builddrafts and canonifyurls are both true.

Working on Your Site

So then, to run your development site, so you can draft your content and work on your theme or whatever, it’s a case of running the Hugo server:

michael@DESKTOP-0V8O7JR:~/personal-site [main ↑1 +2 ~1 -1]$ hugo server -D
Start building sites … 
hugo v0.88.1+extended linux/amd64 BuildDate=unknown
WARN 2021/10/10 06:43:17 Page.RSSLink is deprecated and will be removed in a future release. Use the Output Format's link, e.g. something like:
    {{ with .OutputFormats.Get "RSS" }}{{ .RelPermalink }}{{ end }}

                   | EN  
-------------------+-----
  Pages            | 19  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     | 13  
  Processed images |  0  
  Aliases          |  0  
  Sitemaps         |  1  
  Cleaned          |  0  

Built in 8 ms
Watching for changes in /home/michael/personal-site/{content,data,layouts,static,themes}
Watching for config changes in /home/michael/personal-site/config.json, /home/michael/personal-site/config/development
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

Great, now in my browser I have a site running, which I can see and make changes to. There’s a problem with the older code in the theme I based on using a legacy way of outputting RSS links, so I’ll go and fix that and then get on with writing content.

I’m wondering what my 19 pages are though. I’ve not written anything yet.

Git

Now, any changes I make to the theme, configuration or content are all fully tracked and mastered with standard git commands. Remember when you make changes/commits in the sub-module to commit the change in the main repository to ensure your site is tied to your specific revision of your theme! Excellent! I can always go back!

Releasing Your Site

A release build is made by running the hugo command, this will generate the static site in the public folder. So I’ve tweaked .gitignore to include public/* as an ignore, as I don’t want to version the releases in my repo.

michael@DESKTOP-0V8O7JR:~/personal-site [main ≡]$ hugo
Start building sites …
hugo v0.88.1+extended linux/amd64 BuildDate=unknown
WARN 2021/10/10 07:01:24 Page.RSSLink is deprecated and will be removed in a future release. Use the Output Format's link, e.g. something like:
    {{ with .OutputFormats.Get "RSS" }}{{ .RelPermalink }}{{ end }}

                   | EN
-------------------+-----
  Pages            | 19
  Paginator pages  |  0
  Non-page files   |  0
  Static files     | 13
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0

Total in 29 ms

Later, I’m going to set up a BitBucket Pipeline to auto-build and release to my server when I push changes to main. But not yet. Manual release to start.

cd public
scp -rp * michael@jervis.co.uk:/public

And there we have it, a quick blank site on a basic theme. I still have bundling and minification to look at for the assets, that’s not working. But that’s all you need to get started.

TAGS: HUGO, TECH