A new Hugo theme

My site is built using Hugo. Hugo has a wide range of themes available, which you can browse and preview at their theme gallery. So which Hugo theme am I using? None.

How Hugo themes work

Hugo is really two stacked things:

  1. The plumbing: content model, Markdown/org rendering, taxonomies, pagination, RSS/sitemap/robots (these are internal Hugo templates, free), the asset pipeline, fast rebuilds, and (in my case) the ox-hugo bridge from org-mode.
  2. The theme: just layout templates. The style.

Instead of creating a true custom theme, which is a full package that could be shared on Hugo’s theme page (and would need to be indefinitely maintained and guaranteed portable), I’m taking a different route, and I’m explaining it here in case someone (you) might want to adopt the same plan for your own site.

This current “theme”

My plan hinges on one aspect of Hugo’s functionality: the local project-root layouts/ overrides the theme’s layouts/. This means you can write your own templates one file at a time while the theme stays installed, and each file silently takes over that page type. You also don’t need a template for every page type - Hugo has a fallback chain, and the minimal complete set is just _default/baseof.html, _default/single.html, _default/list.html, index.html, and 404.html.

Start with those, and then each other component of the layout can be replaced, one by one, tweaking to the result you want on your own site. Eventually, when every single thing has been replaced, you can just delete the entire theme line from hugo.toml. At that point, everything is coming from your own collection of layout files, and they form your custom theme.

A true theme is more than just layouts, it can inject assets/, static/, default params, i18n/, and archetypes/. Those still merge even when the layouts are fully shadowed. So if you don’t want those from the theme, you will need to do the full removal, deleting that theme line from hugo.toml. And to get there, you need your own templates covering every page type your site actually produces - not necessarily every template the theme ships, since it probably includes layouts for page types you’ll never use.

So here’s my basic workflow in creating this current “theme”:

Start with a basic theme. The more complete the theme, the more of your site’s behavior hides inside the theme’s files instead of yours - so when you finally remove it, you’ll discover it was doing more than you realized. I started with hugo-bearcub. I tweaked each aspect of the theme using my own file in layouts/ until I no longer needed that theme, and I deleted the theme = 'hugo-bearcub' line in hugo.toml.

You might expect at least one surprise when you do. In my case the theme had been quietly supplying robots.txt - with a Sitemap: line in it - and Hugo’s built-in version has neither. Nothing looked broken, because nothing looked like anything; it was a file I’d never written and didn’t know I was relying on. Part of the argument for doing the removal instead of just shadowing the layouts and calling it done.

Then I browsed around Hugo’s theme gallery for the more feature-rich themes, looking for specific things I’d want to incorporate into my own site. When I found something, I edited/created a file in my own project-root layouts/ directory, and magically that feature/component shows up in my own site.

Hope that’s helpful for anyone wanting to get a custom look on their Hugo site.

← Back to Blog