Chris Wiegman

My Hugo Theme Continues to Evolve

| 4 min read
My Hugo Theme Continues to Evolve

Last fall I moved this site back to Hugo and resumed work on its theme. I haven’t written much about the theme itself since then, so it feels like a good time for an overview of what’s actually changed under the hood.

None of this was one big redesign. It’s been a lot of small releases, sometimes a few in a single day. Each one nudged things forward, but looking back at the changelog, a few themes stand out.

A New Coat of Paint

The most visible change was a full color refresh back in the spring. It was intentionally a breaking change: I wanted an excuse to actually sit down and rethink the palette instead of tweaking it forever. It’s more “earthy” than my previous palette and just feels more like me. Everything since then has been built on top of that, and I love it so much that I’ve turned it into a VS Code theme, an Xcode theme, and more.

I’ve Added a Library

The library has probably gotten more attention than any other part of the theme this year. It started with the goal of backing up my Goodreads history and has since grown to include filtering by year, author, and rating, along with summary cards for years and authors. Along the way I fixed a few bugs and tweaked the design here and there and now I’m pretty darn happy with it.

Under the hood I also added ISBN, ASIN and cover image support to book front matter, which finally made the covers reliable instead of a guess (even though I don’t display them yet).

When I launched it, I displayed all the books at once, which didn’t make much sense. I later added manual pagination, but as of this week, the list loads progressively as you scroll, which feels a lot more natural on a page like this.

Alongside that change, I refactored the underlying script to make it simpler and faster.

Faster, Leaner Pages

A lot of the less visible work went into performance. Content images now get a proper WebP srcset through a render hook, load lazily when they’re offscreen, and let the browser select an appropriately sized image instead of always downloading the largest one. Header images received the same treatment, and the search index is now truncated so its payload doesn’t balloon on larger sites.

I also cleaned up some things that were quietly working against performance and correctness, like a fetchpriority=high hint that had leaked onto content images instead of staying reserved for actual LCP elements.

Cleaner Feeds and Metadata

RSS took a few passes. Feeds broke and got fixed for newer Hugo releases, notes finally got their own working RSS feed, and the main feed’s dc:creator field is now configurable through site parameters instead of being hardcoded. I also replaced the old schema.json approach with a proper JSON-LD header, and standardized how page and feed titles are formatted so they’re consistent everywhere instead of ad hoc.

Small Stuff That Adds Up

The rest was a lot of polish: a skip-to-content link, a noscript fallback for search, datetime attributes on post timestamps so the semantics are actually correct, the monospace font was finally removed from blockquotes so quotes stop looking like code, and a handful of favicon fixes (Safari really did not like the old one).

A Better Development Workflow

None of this would have been as easy to keep shipping without the boring maintenance work alongside it. I added ESLint and switched to Hugo’s own gotmplfmt formatter for templates, migrated the dev site config from hugo.json to hugo.toml, and kept dependencies current with pretty much every release. There were also a couple of straight-up refactors just to cut cruft out of the codebase, with no user-facing change at all.

I’m Loving This Work

What strikes me looking back over all of this is just how steady the pace has been. No big rewrites, mostly a lot of small, deliberate improvements. That’s exactly the kind of work I want to be doing with this site right now, and I’m looking forward to seeing what the next few months of changes look like.

As a bonus, I’ve made this all available for your site at kana.sh