Blogging With Hugo

Blogging with Hugo

There are so many options for static site generators today, it can be a bit overwhelming to pick one if you’re not entrenched in a language. Even after selecting a hosting provider like GitHub Pages, there are still so many choices! When it came time to choose a framework for bashfulmusings.dev, there were three primary factors influencing my decision:

  1. I am taking every opportunity I can to increase my proficiency in golang.
  2. I wanted a static site generator that has themes that resonate with me.
  3. I have a cat named Hugo.

Creating the site

The first step is to create a repo on GitHub and lock down the main branch to require reviews. Even though I’ll likely be the only one to ever contribute to this site, I’d prefer to have it set up for collaboration just in case.

With the repo created, next I clone it onto my debian dev machine, which conveniently already has the extended version of Hugo installed 😎

Time to issue the commands to actually create the Hugo site:

git checkout -b site-creation-dev
hugo new site --force

The above code creates a new branch and checks it out. Pushing this branch to GitHub with our changes will create a pull request that facilitates the merge into main. Second, the hugo new site command needs the –force switch to allow the site to be created in a non-empty directory.

At this point, Hugo has setup a very basic site structure without a theme. It’s simple to add one in the hugo.toml file (along with a few other necessary pieces of metadata):

# hugo.toml
baseURL = 'https://bashfulmusings.dev'
languageCode = 'en-us'
title = 'Bashful Musings'

[[module.imports]]
path = "github.com/CaiJimmy/hugo-theme-stack/v3"

In the above toml config file, the theme is defined using Hugo modules. Hugo modules naturally build on Go’s dependency management system to piece together code from several projects; a theme component is the most basic use case for Hugo Modules since its code from someone else’s repo (hugo-theme-stack in my case).

hugo mod init bashfulmusings.dev
hugo mod get -u github.com/CaiJimmy/hugo-theme-stack/v3
hugo mod tidy
hugo server

That’s it for the basic site structure! The last command launches the server for local testing. Running just hugo will create a public directory, but at this point, I’m ready to leverage GitHub actions to deploy to Live. GitHub and Hugo both hav pretty extensive documentation on configuring actions, so I won’t describe that here. After this configuration, all that’s necessary is to commit, push, and merge via a pull request!

The first post

Getting a site live always feels good, but I don’t get into a groove until I start publishing content and trying to make everything fit together exactly how I want. With any static site generator, there are expected patterns that, if followed correctly, allow for pieces to fit together without a lot of work. Even just getting the first post to populate on the site takes some consideration. In Hugo, for example, I know I can count on page bundling to keep all the content relevant to a particular post in a single directory. Furthermore, I can count on Hugo’s branch bundling to create a list of posts where necessary. The biggest gotcha in my case was a name mismatch that prevented my theme from surfacing the posts on the home page. Essentially, I created the first post using the exact syntax from the Hugo docs:

hugo new content posts/post-1.md

By looking at my theme’s templating code, I could see that it was expecting my posts to be in a directory called “post” (not “posts”). Although there are several ways to override templating behaviors, it’s acceptable to me to just add the url I desire in my post front matter. In the end, instead of having a file with the post name in the filename, each post has its own directory and an accompanying index.md.

Finally, serve the draft content, test, commit, push, pull request, 🎶

More Site Configs

The last setup related item is the menu, which I decided to define in hugo.toml

# hugo.toml
# ...
[menu]
    [[menu.main]]
        name = 'Home'
        weight = 1
        pageRef = '/'
        [[menu.main.params]]
            icon = 'home'
    [[menu.main]]
        name = 'Posts'
        weight = 2
        pageRef = '/post'
        [[menu.main.params]]
            icon = 'archives'

Wrapping Up

There is a lot more that can be done with Hugo, but the starting journey is a fruitful one. Thanks to the open source community for making these great tools available to those of us trying to share our knowledge with the world.