Hugo's "default" theme

When I was updating the tutorial, I thought about adding an overview of themes because of some chatter on this forum. Entry level users seem to get confused about “layouts” versus “themes.” My take is that the notion that it is a “layout” if it’s not in the “themes” directory contributes, so it’s an unnecessary distinction. The distinction that’s important is that these “layout” files override the corresponding “themes” files.

I used “default” in the article below. It doesn’t ring quite true, though. So, I’m asking for your opinion - is there a better way to describe it? (Assuming that you’re looking at this from that same entry-level perspective.)

The Anatomy of a Theme

Hugo themes are built around a standard directory structure. Hugo relies on that structure to determine what to do with your content.

Every theme has archetypes/, layout/, and static/ directories. Some themes may also have data/.

  1. archetypes/ contains files that are used by the hugo new command to help create content files.
  2. layouts/ contains the template files that Hugo uses to build your HTML files from your content files.
  3. static/ contains CSS, JavaScript, and other files that are copied into your web site. Static files are not changed in any way by Hugo.
  4. data/ contains files that the user updates to supply information to a theme.

There are two types of themes: the “default” theme and named themes. The difference is that named themes are placed in a sub-directory of the site, themes/nameOfTheme, while the “default” theme is placed in the site’s root directory.

The Default Hugo Theme

Hugo has no opinion on what your web site should look like or what content it should contain, so when you use the hugo new site command to create a new site, it creates an empty (and unamed theme) in the site’s root directory:

$ hugo new site hugo-0.16

$ find hugo-0.16 | xargs ls -ld
drwxr-xr-x  8 mdhender  wheel  272 Nov 27 11:39 hugo-0.16
drwxr-xr-x  2 mdhender  wheel   68 Nov 27 11:39 hugo-0.16/archetypes
-rw-r--r--  1 mdhender  wheel  107 Nov 27 11:39 hugo-0.16/config.toml
drwxr-xr-x  2 mdhender  wheel   68 Nov 27 11:39 hugo-0.16/content
drwxr-xr-x  2 mdhender  wheel   68 Nov 27 11:39 hugo-0.16/data
drwxr-xr-x  2 mdhender  wheel   68 Nov 27 11:39 hugo-0.16/layouts
drwxr-xr-x  2 mdhender  wheel   68 Nov 27 11:39 hugo-0.16/static
$

This theme, the one we’re calling the “default” theme, is special because Hugo always looks there first to find files when rendering your web site.

You’ll notice that the “default” theme doesn’t include any files (the config.toml is part of the site, not the theme). There are no files, so there are no rules, and no output in your public/ directory when you render your site. That leads to the saying “Hugo doesn’t have a default theme.” It’s confusing at first but it should make sense by the time we’re done.

These directories, since they’re searched first, provide an easy way for end-users to override parts of a named theme. For example, if a named theme provides a template that set the heading level to 1 for articles, the user could copy that file from the named theme into these directories and change the H1 to H2. When Hugo next runs, it would find the file in the “default” theme and use it to create the site.

On the surface, that seems like odd behavior, but it’s actually a very good thing. It allows users to easily customize your theme without changing any of the files in your theme. That makes it very easy for them to update their sites when you release an upgrade to your theme since their changes are completely outside of your theme.

Named Themes

Named themes are created with the hugo new theme command. By default, they’re created as sub-directories of the themes/ directory in your site’s root directory. (Don’t worry, Hugo will create the themes/ directory if needed.)

# show the directories created by the new site command
$ find hugo-0.16 -type d
hugo-0.16
hugo-0.16/archetypes
hugo-0.16/content
hugo-0.16/data
hugo-0.16/layouts
hugo-0.16/static

# create a new theme named "zafta"
$ cd hugo-0.16
$ hugo new theme zafta
$ cd ..

# show the directories created by the new theme command
$ find hugo-0.16 -type d
hugo-0.16
hugo-0.16/archetypes
hugo-0.16/content
hugo-0.16/data
hugo-0.16/layouts
hugo-0.16/static
hugo-0.16/themes
hugo-0.16/themes/zafta
hugo-0.16/themes/zafta/archetypes
hugo-0.16/themes/zafta/layouts
hugo-0.16/themes/zafta/layouts/_default
hugo-0.16/themes/zafta/layouts/partials
hugo-0.16/themes/zafta/static
hugo-0.16/themes/zafta/static/css
hugo-0.16/themes/zafta/static/js
$ 

Hugo created themes/zafta/ for us, then added the archetypes/, layouts/, and static/ directories for us. That’s exactly the same structure as for the “default” theme.

Hugo also created quite a few files for our theme:

$ cd hugo-0.16/themes/
$ find zafta | xargs ls -1d
zafta
zafta/LICENSE.md
zafta/archetypes
zafta/archetypes/default.md
zafta/layouts
zafta/layouts/404.html
zafta/layouts/_default
zafta/layouts/_default/list.html
zafta/layouts/_default/single.html
zafta/layouts/index.html
zafta/layouts/partials
zafta/layouts/partials/footer.html
zafta/layouts/partials/header.html
zafta/static
zafta/static/css
zafta/static/js
zafta/theme.toml

The important ones are the template files, which end in .html.

$ find zafta -name '*.html' | xargs ls -l
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/404.html
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/_default/list.html
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/_default/single.html
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/index.html
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/partials/footer.html
-rw-r--r--  1 mdhender  wheel  0 Nov 27 12:06 zafta/layouts/partials/header.html
$ 

The template files are all empty because Hugo doesn’t have an opinion on what your site should look like. In effect, that new theme acts just like that “default” theme. The main difference is that Hugo created the most commonly used template files as a convenience to you.

Using the Default Theme

Hugo will always check first for files in the “default” theme. ?TODO? There is no way to change this behavior.

Using a Named Theme

Hugo will only use a named theme when told to do so. You can do that on the command line with “--theme=zafta” or by adding a line to your configuration file ("theme = "zafta").

2 Likes

How about impartial observer instead of no opinion? Although that sets up some tension with theme/layouts/partials.

I agree that the Hugo docs need a good introduction on Themes, but the “default” theme idea presented here is more confusing to me.

I don’t consider the site files a theme at all, and trying to call them one complicates something that’s not that complicated. Additionally, the use of “Default Hugo Theme” makes it sound like Hugo ships with a default, embedded theme so that I don’t need to create any layouts at all.

Instead, I would simply explain that, first of all, a site doesn’t need a theme. Show a simple, non-theme directory tree. Then explain the benefits and anatomy of a theme. Then show a directory tree of the same site with all of the “theme-able” elements moved into a theme. I’d then give a pointer to the Customizing a Themes page that discusses supplementing and overriding elements (you could even work in links to all the other Themes pages in the docs). And that would be a good introduction to themes.

1 Like

2 posts were split to a new topic: Some beginner questions about themes