As a happy Hugo user, this is not a post I had expected to be writing.
However, I've decided to begin migrating my blog from Hugo to Zola.
There are a couple of reasons for this. None are especially convincing.
First: I find editing Hugo templates difficult. I don't gel with the documentation, and the overall experience with Hugo's Go Templates tends to feel unintuitive pretty quickly.
Having become frustrated by this once again, I took the natural course of action: I searched for alternative static site generators.
After revisiting the usual suspects, I stumbled across one I hadn't tried before: Zola.
First impression: the docs were clear, organized, and easy to follow. That matters to me.
Also, Zola is packaged in Arch Linux's [extra]
repo, which helps.
There appear to be fewer Zola themes available than themes for Hugo, but enough variety to get inspired to start a test project.
Running zola init <site-name>
got me up and running quickly, and following along with the Getting Started section in the docs was pleasantly straightforward.
There were a few hiccups, though.
The first was how taxonomies are defined in front matter. Coming from Hugo and having not read the docs carefully (plus being unaccustomed to writing front matter in TOML), I missed the fact that taxonomy table declarations need to be explicitly stated before attempting to set a post's tags.
+++
title = "My first post"
date = 2025-05-20
[taxonomies] # <- This is important
tags = ["blog"]
+++
Another issue: I like to use a post slug structure that includes the year and month (posts/<year>/<month>/my-first-post
), which also mirrors how I arrange the files on disk. It keeps things tidy, which matters when post content starts to accumulate.
Zola’s paginator wasn't finding the posts I had placed in subdirectories under content/
.
content/
_index.md
posts/
my-first-post.md # <- Zola doesn't see this
At first, I tried adding an _index.md
to the posts/
directory. No change - but I was getting closer.
After reading the Section docs more carefully, I found the key: the transparent
attribute. This was the missing piece. Marking the posts/
section as transparent
flattens its children into the parent section for listing and pagination.
# content/posts/_index.md
+++
transparent = true
+++
To support my desired directory structure, an _index.md
with transparent = true
set needs to be added to each nested subdirectory.
content/
_index.md
posts/
_index.md # <- transparent = true
2025/
_index.md # <- transparent = true
05/
images/
static_content.png
_index.md # <- transparent = true
my-first-post.md # Zola will now pick up on this post
From there, the rest of the site setup went smoothly. RSS feeds work out of the box, and I had no issues finding and applying a theme - zola-theme-terminimal, in this case.
By this point, having worked through a variety of small issues along the way, I was feeling fairly comfortable with how Zola was working. Tera seems more intuitive than Hugo's Go Templates, which makes the occasional tweaking of themes less of a burden.
I'm staying with Zola for now, and I'm looking forward to learning more about the Zola ecosystem.