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 127.0.0.1
, 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.