Two Further Hugo Gotchas

I just wasted one hour and five minutes, dealing with two of these opaque, unexpected, and almost undiagnosable showstopper roadblocks that Hugo will throw your way - much too often, in my opinion.

One Hour

The Hugo development server, by default, binds to localhost only. It does not bind to the actual network interface.

This means that you can access the test site, with no problem, from your development box, using http://localhost, but you won’t be able to see it from (e.g.) your phone (in case you would like to know how your site renders on a handheld device).

To have the development server bind to an externally visible IP address, you need to give it the --bind option. The help message says that this option takes as argument “the interface to which the server will bind”, but that’s not strictly correct: it requires an IP address (not an interface name, like eth0 or eno1).

Should I have expected this behavior? I don’t think so! Neither the Python webserver python -m http.server, nor the busybox httpd server, not even the GoLang http.ListenAndServe() server exhibit this default behavior - they all bind to the host’s IP address!

In truth, the Hugo server informs me on startup that its bind address is, but all the other servers mentioned earlier will also be available at this location (in addition to the proper IP address), so this hardly alerts me to the fact that Hugo will not be available publicly. In particular given that other servers usually are.

It’s not primarily the behavior that’s a problem here, but the messaging: if you do choose to behave differently than what is common and what users can therefore reasonably expect, then you should really be vocal about it!

Five Minutes

Hugo will not publish posts with a frontmatter date that is in the future. Instead, if will silently discard the post. Note: the time of day (and hence the timezone) matter; it’s not just a question of the calendar date.

The issue here is not so much whether this behavior makes sense, although I personally don’t think so. (In my opinion, the “date” of a post is just a value, for display and sorting, but should not determine the functioning of the tool.) But what bothers me to no end is that Hugo silently discards input, without telling the user. (Setting the --verbose flag does not seem to make a difference.)

This only took me a few minutes to figure out, partially because I have gotten wise to the way Hugo treats dates, but also because I remembered that I had fiddled with the date entry in the frontmatter.

It’s Poor Design, not a Feature

I occasionally hear “Hugo is great, it’s just the documentation that sucks”, but I can’t agree. The problem with both of these gotchas is that Hugo does something that’s unexpected and then fails to alert the user to this unexpectedness. For both issues, Hugo’s behavior is likely to trip up an unsuspecting user - even if the behavior was very clearly documented.

It’s not a documentation issue; it’s a design issue: good design adheres to the principle of “least astonishment”, and that means following established conventions. If you choose to deviate from what a user can reasonably expect, then you should at least make this really, really obvious.