Introduction to Hugo static website generator

Why would you even consider using Wordpress, when all you really want or need is making a completely statically generated website? logo


Motivation for going static

Not long ago, Paul Vixie argued that every web-page should go static. But, besides security aspects, overall maintenance remains the number one issue with dynamic site systems.

Whenever you use a dynamic site, aka. CMS, a lot of moving parts are involved. You probably need a database and a framework written in some programming language.

The setup has dependencies, hand-written code, libraries must be updated, configuration settings for various environments exist. Deployments can go awry.

So, you have to constantly have an eye on those things, at times, making deployments just for the sake of updating components, without any changes to the actual content.

In the end, there is no time to waste on all the moving parts that make up a dynamic content-management system. Instead, you probably want to focus on the most important thing: your content.

Static site generators to the rescue

There are many static site generators out there to choose from, almost all of which serve their purpose well.

Advantages of going static

Challenges when going static

Your mileage may vary, but most - if not all - content-driven sites can be made entirely using a static website generator.

What makes Hugo stand out?

Hugo is for people that prefer writing in a text editor over a browser. Hugo is for people who want to hand code their own website without worrying about setting up complicated runtimes, dependencies and databases. – Steve Francia

Written in Go, Hugo has absolutely nada, nil, NO external dependencies. Distributed as a single standalone binary it just works on any operating system.

Rendering speed is ultra-fast: A site with 100s of pages takes a fraction of a second to render.

Everyone who has had experience with CMS products will immediately recognize the basic building blocks of content management are all there:

The tools given to you allow for an extremely flexible site structure.

There are many built-in template helpers that make life as a content editor easier. To name just a few:

Hugo has extensive theming support to enable switching presentation and layouts quickly without affecting content. It also has a well implemented system of translating and offering multiple language versions.

My personal favorite feature by far is Hugo’s ability to seamlessly integrate data-driven content from anywhere in the Internet. Load (external) JSON or CSV-files and use the data for generating content or partials.

Lastly, the development workflow is amazing. Typing hugo serve runs your site as is on your local computer. Any change made will be immediately visible due to the use of live-reloading.

Before you get started

After all this hype, let me point out a few lessons I had to learn the hard way, though:

Golang templates are nothing for the faint hearted! There are intrinsic rules for when you can inherit templates, and when you must include them explicitly. It’s easy to forget to pass in the current context into a partial or use the wrong context.

Secondly, also template engine related: I have yet to find an IDE or code editor which isn’t super confused about the syntax of go-templates. If you’re developing a theme or deal with layout files, you’ll get tons of useless error and warning messages.

Thankfully, Hugo let’s you choose different template engines. Amber template engine looks like a decent choice, if you’re familiar with Jade/Pug.

Taxonomy and term handling is a bit rough around the edges, e.g. you cannot paginate terms in a given taxonomy grouped by number of posts easily. (Or maybe it’s possible and I just missed to read the last couple of release notes …).

Speaking of which: Implementing paginated post lists with filters on post-type / publishing-date can become a bit cumbersome. Things get tricky, when you end up writing complex slice operations.

RSS-feed names names are “hardcoded” by default and are called index.xml. Recent Hugo versions introduced custom output formats, so you can disable automatic feed-generation and provide your own if you find that naming not to your liking.

There have been issues with posts missing the draft=true flag in the frontmatter, suddenly appearing as next-in-section.

When creating a post with hugo new -k <type> the creation date is automatically inserted, but setting or updating it (same goes for lastmod) must be done manually. In general “date” handling is not very automatic.

Long-term organization of media files and content require you to come up with a sensible scheme. For a simple blog, it makes sense to prefix posts’ filenames with a date.

Nothing of the above is a deal breaker, but can be irritating at times. Also, Hugo’s development is progressing in a steady pace, so improvements are made over time, all the time.

No looking back

Hugo is an excellent choice, if you’re looking for a fast and flexible static website generator. The development workflow with live-reload requires absolutely no setup, nor has it external dependencies. It is just a pleasure to work with.

Have a look at some of the tools and frontends the Hugo community has created. There, you can also find importers for common CMS systems.

If anything, I hope I made a convincing argument to drop Wordpress like a hot potato.

In an upcoming post, I’ll explore some hacks, tips and tricks, and workflow styles I find useful.