Tell me why

In 2023, I decided to rebuild my website that I first put online around 2016. At the time, it only featured basic JavaScript games that I coded when learning web technologies. It was a very basic handmade static website but served as a continuous experiment. As such, I regularly updated its content and implemented good practices that I acquired over time (responsiveness, SEO optimization, switching from FTP to Dockerization, HTTPS with Let’s Encrypt…). However until now, I never really updated the website design because, and I cannot stress this enough, I am not a designer.

Updating the old website in production presented a particularly thorny challenge. Indeed, the site was served as-is through NGINX, which is totally fine, but the repository that contained the website was not properly linked to the git repository and I never took the time to fix that mess because I enjoy chaos. Consequently, every time I wanted to update the website, I found myself manually sifting through the codebase to separate the wheat from the chaff.

Long story short, in 2023 I though it was time to start fresh and test that Hugo static site generator I heard about.

Screenshot of the old website

Here comes troubles

Great ! What an exciting adventure !

Let’s follow that Hugo tutorial. I download the executable, type a few funny commands and choose a theme. At this point, I don’t really known what I am doing with the configuration BUT it works and it looks nice so let’s go on.

Quick start

The Hugo documentation offers an efficient quick start, but very abruptly turns into a comprehensive manual covering all Hugo’s features. It is a good thing to have an exhaustive documentation. However, it makes it challenging to learn Hugo, as navigating the technical documentation and filtering out the more advanced concepts in order to grasp the core explanation becomes a daunting task.

I would have preferred a more guided tour of Hugo’s features, punctuated with good practices. A good example of such a documentation is the ReactJS one. It underwent a complete overhaul around last year and now focuses more on actually teaching ReactJS instead of just listing features. The following figure is a good example of that and features a code playground integrated in the ReactJS doc, so beginners can directly test what they’re reading.

Screenshot of the code playground in the React documentation

You might expect a static site generator to be relatively beginner-friendly because creating a static site is a good first project to train oneself. Consequently, you’d anticipate finding more resources tailored to beginners. Even experienced developers could benefit from a structured learning path, covering essential topics in an ordered manner (like simple page editing, then templating, partials, shortcodes, and pipes).

In my experience, I had to adapt my learning approach and figure out myself what were the best choices among the various solutions I researched. This lead to temporary messy code which can be quite frustating.

Finally, the documentation lacks a guide on best practices. Am I supposed to modify the theme’s stylesheet directly or should I override it, potentially necessitating code duplication ? When building a complex page, should I create a custom templates or a .html page ? And the internet, known for its contradiction, doesn’t provide much help either on that matter.

Not a blog

My first realization came when I started to build the home page. I actually wanted to do something quite custom for that page, with my avatar on the right and a list of curated pages. Except that, Hugo and the theme I chose work really well to build a blog with pages that all have the same template. Also, they can be written as a simple markdown document, in the same manner as Docusaurus (we have it at work, it is awesome). Thus, to build the custom pages I wanted I had to create my own templates with their own logic and style. Turns out, it was going to be slightly more work than anticipated.

Just one more icon

While working on custom pages, I inevitably needed to modify the theme I had initially chosen. Fortunately, the author of the Poison theme published the code for its demo site, allowing me to see for myself how he customized his own theme. However, I ultimately decided against using the theme as a git submodule. The reason being, I would have had to copy entire template files just to add a simple icon. I opted instead to directly copy the poison theme in my project. It works for me because I have no intent to update the theme, so I can safely detach from the remote git repository.

How long can it take to add an icon ? 5 minutes ?

— A product-owner, sometime in the last decade

This solution allowed me to directly modify the theme’s files. But, in adherence to best practices, I kept on creating my own layouts when the context felt right (i.e. when minimal code copying was involved). Typically, the entire portfolio section is inspired by the theme’s blog templates, and thus all sorts of links where generated at the bottom of those pages. To address this, I created specific templates for the portfolio, inspired by the blog ones, and I got rid of all the useless parts (links, comments…).

Red squiggles

I wasn’t able to get the Hugo VSCode extension to function properly. To be honest, I did not insisted, laziness is a recuring theme with me (but the best developers are the lazy ones apparently). Anyway, this situation has made developing Hugo templates quite tedious, especially when dealing with shortcodes that involve lots of intricate instructions. Even setting aside the issue of color syntaxing not working and the red squiggles, it makes reading long templating instructions very challenging. Moreover, I feel like I miss useful information when developing templates. For instance, I frequently wonder about the available variables I can access (.Pages, .Site, .Params…) and their structures. A little autocompletion for Hugo methods would have greatly helped me.

This is particularly true because I feel that the templating syntax is very different from what I have experienced before (cshtml and twig). It actually is quite close to assembly language, which is surprising when it comes to mathematical operations. They are written as operator arg1 arg2 whereas any other language would use standard mathematical symbols (+, -, *, %, ^…). Yes, 1 + 2 in Hugo is written add 1 2.

Code for a custom img shortcode

In the previous figure, the code is not unreadable but there are still red squiggles in the CSS part even though the syntax is perfectly valid. Also, the HTML attribute parsing is all other the place because of the templating. Maybe I have not properly set the extension up but to be fair, as for any language extension I shouldn’t have to do more than clicking the install button.

What’s good


As mentioned in Quick start section, I realized that in the old site, I had loosely integrated the oldest JS games by simply copying the HTML files instead of properly integrating them into the site’s design. This time, I decided not to repeat the same mistake, but I also wanted to stay efficient. I opted to simply ctrl+c ctrl+v-ing the HTML into the Hugo pages while embedding the CSS in style tags. Mathieu Nebra would not be proud of me, but I’m sure he’ll forgive me.

I anticipated potential conflicts between the CSS of the JavaScript games and the theme’s styling, but thanks to the higher specificity of the style tag and the encapsulation of rules within the article selector, I had minimal corrections to make. It’s worth noting that the theme’s style complemented the games’ style quite seamlessly, making them suitable for both dark and light modes. That’s also because I had adhered to HTML semantics when originally coding those games years ago.

However, due to a lack of time and usefulness, I chose not to setup SCSS in Hugo, in part because all of those old pages are in raw CSS. Well, the few lines of CSS I had to write reminded me why SCSS is nothing short of a modern miracle

Automate everything

The primary benefit of static site generators is that they automatically generate a lot of tedious code, such as sitemaps or taxonomy pages for SEO purposes. If I had to do all that myself, I might’ve died of boredom! Okay, maybe that’s a bit of an exaggeration, but it definetely is a pleasing feature.

One time setup

As explained earlier, I had a hard time crafting custom pages that weren’t included in the theme, such as the welcome page or the portfolio. However, now that it is done and dusted, it is very easy for me to add content to the site. Once the initial setup is done, adding a page consists only in redacting the content of such a page and deploying the site again. It seams obvious, but after a week of work it is very satisfying to experience it.

Let’s go live

Because I’m not particularly fond of the DevOps aspect of website creation, I took me a while to find the motivation to launch the site. I feel like it often involves dealing with obscure configurations that are hard to troubleshoot. Fortunately, the actual building process is stupidly easy, and after that, it’s simply a matter of using your favorite web server to make it available online. In fact, automating this process requires no more than a 4 lines long script.

However, my fear where not completely unfounded, as I did have to make a few adjustments to my original nginx configuration (regarding the CSP rules and the 404 page). Additionaly, I spent about 20 minutes realizing that I had an older version of Hugo in my Docker image, causing my build to fail. This was partly due to Hugo not providing an official Docker image, and the recommended one is only sporadically updated (plus, the latest tags featured in the readme were not the latest tags 🫠). I don’t blame the guy maintaining Hugo images, it should be an automated task by Hugo.

Wrapping up

Although it was a challenge to rebuild, it all worked out in the end. For an experienced web developer, the learning curve isn’t overly steep, but it still misses the comfort of a mature technology, whether it is in the development environment or the learning documentation. Many of the issues I encountered gradually disappeared as I became more acquainted with Hugo. I’m not entirely certain if I would recommend this technology to novice web developers, but for creating a personal blog with some degree of customization, it works well.