Hugo - Switching to Static Site Generation

August 12, 2017


It's been quiet here for a while, again. I keep busy and needless to say, don't get around to writing about all the things I've been working on. Like I'd like to do! In the last year, I've been fortunate to start a new software job which has also freed me up to playing with new environments and experiences. I've also been making larger pushes to contribute to the open source world; specifically the FW/1 ecosystem with the FW/1 Console CommandBox module; formerly FW/1 Commands. More on that another day...

Hugo & Blogging

Part of dragging me down with blogging was the initiative I took years ago to write a custom blogging engine in CFML. Ironic right? It's stayed fairly incomplete and has slowly become a chore. So why not use an existing framework? Well... I'm stubborn, and a bit specific to control when it comes to this kind of stuff. I'll admit that some of these limitations are merely my lack of understanding, but I like when I can follow along.

Some time now, I had read a series of articles from Raymond Camden about his switch to static site generation and the use of Hugo. I'd done some research on static site generation and the frameworks that came with the territory. Hugo stuck out. I figured I'd give it a try.

Getting Started

Hugo, if you haven't guessed, is a framework written in the Go programming language and used for building statically generated websites and their content. The ability to create a structured pattern of pages makes Hugo perfect for a blog.

So I took the leap, set Hugo up on my dev machine, and started plugging away at converting my blog application to a Hugo site. Not difficult at all. I created a site using the Quick Start Guide, installed a theme and basically just used the example posts in the theme to lay out how my original posts would need to look. Everything is in Markdown which saves a bit of formatting time with the actual content. After I had everything in place, I took some time to familiarize myself with Go template syntax and took to tweaking the layouts and styling.

Personal Caveats

There were a few things that I had to iron out based on the structure of the previous application and my personal preference.

URLs, Redirects & Rewrites with Nginx... Bleh.

First up, I wanted to try and keep as much of my current URL structure as I could. By default, Hugo will generate URLs like /page/my-page and /post/my-cool-blog-post. I wanted things slightly different. For example: /my-page & /blog/my-cool-blog-post.

Luckily Hugo makes this simple with a decent amount of flexibility. Each site comes with a config file that can be written in different formats like TOML, YAML & JSON.

I just needed to enter these config points and I was good to go.

  post = "/blog/:slug/"
  page = "/:filename/"

I needed to tweak the pagination URL as well...

paginatePath = "blog/page/"

There were some areas with URL paths I don't think I can get around through configuration. Nothing I have found at least. Two areas specifically were the main RSS page and tags/categories.

The RSS is generated into an index.xml file. Previously I had a nice route to a path like /feeds/rss and /feeds/atom. No worries though. I use Nginx as my web server so rewriting the path or even redirecting is simple enough.

location ~* /feeds/(rss|atom) {
  rewrite /feeds/(rss|atom) /index.xml;

I haven't started using Hugo's categories, but I am using tags. My previous URLs looked like this: /archives/category/my-category. I used a rewrite but a redirect is just as well if I decide to permanently keep this pattern.

location ~* /archives/category/(.*)? {
  rewrite /archives/category/(.*)? /tags/$1;
# OR
location ~* /archives/category/(.*)? {
  redirect 301$1;

Disqus & Forum URLs

When I was finally ready to go live, I was unpleasantly greeted with posts that were not showing their comments. In fact, Disqus was rendering as if they were new forums. A quick trip to the admin showed me the culprit: a trailing forward slash, /. Based on the default way that I had originally identified Disqus URLs, and how Hugo's built in support for it, the exact URL path was used to identify each forum. For example /blog/my-post is different from /blog/my-post/. To make things more frustrating, after some research, it seems Hugo requires that trailing slash to maintain cross platform support. No rewrite or redirect will save you.

So what I had to do was export my forums and their comments and then submit new URLs with the added / via Disqus' migration tool. All good now.

Moving Forward

I've more or less ironed out the gritty parts of my blog. Some pieces will just have to be left behind or dealt with later on. Overall I'm happy with the result and will hopefully be able to start pushing out some helpful content here, once again. Hugo FTW.

Happy coding.