In case you've stumbled on this page without knowing what Hugo is, allow me to provide some quick context. Hugo is a static web site generator that takes content files and converts them to static web site HTML and CSS pages. These content files are written using markdown. Markdown is a simple encoding system for formatting a document.
Hugo is different from a CMS like Wordpress or Umbraco because web pages are not constructed dynamically using content from database. Because there is no processing required to dynamically format pages static site are very fast. There is no admin console or back-end database, this helps keep static sites secure.
First, the quick answer, but I will go through a detailed example to make this clear.
Hugo themes go in the themes folder of your site. To tell Hugo to use a theme you need to update the site config file (typically called config.toml) stored in the site root. The following is an example of a site that uses the twenty-twenty-hugo theme. This theme has been pulled from a GitHub repository into the themes folder of a new site. The config.toml file contains this entry.
theme="twenty-twenty-hugo"
Let's go through the steps to create a Hugo site to show how themes work. I am assuming you have Hugo installed and a terminal console open. To confirm Hugo is installed run the following command.
hugo version
I am running version 0.72 for the examples in this post.
Switch to a directory where you want to keep your site files and run the hugo new site command:
hugo new site testsite
This command should create a new site and list the steps to add a theme:
Add Git source control to the new site.
git init
It's important to understand that themes don't just define the look and feel of your site, but they also extend the base Hugo data schema known as Front Matter. The data schemas are defined in the archetypes folder. The test site we just created has a single file in this folder called default.md with 3 data fields:
It is important to note that Front Matter is not common across themes, so you can't expect that your content files will allow you to switch themes to try them out.
Let's download a theme from themes.gohugo.io.
I'm going to use the roxo theme. To add a theme from github you've got some options. The generally accepted practice is to add themes as git submodules. The command to do this for our example is as follows:
git submodule add [email protected]:StaticMania/roxo-hugo.git themes/roxo
Make sure you have initialized the testsite as a git repository (git init) before attempting to add a submodule.
Using git submodules can be a bit a nuisance, and you are likely not going to be updating the theme and pull requesting your changes. I tend to download the theme code in Zip form and extract the files to my site's themes folder.
Every theme should come with an example site. The Roxo theme has a folder directly under the theme folder root called exampleSite. Since there is no standard data schema for Hugo sites the example pages are extremely useful for getting started with a theme.
To run the Roxo example site copy folders and file from /themes/roxo/exampleSite/* to the testsite/* folder.
If you are running Linux, the copy command would be:
cp themes/roxo/exampleSite/* .
You will have to merge the content directory. Once the example site is copied, you can run it in preview mode.
In Photo editing there is a concept of non-destructive editing. This means that the original image is left intact and edits are applied additively and can always be undone. The original image is never irreversibly changed; changes are added as layers on top.
This non-destructive practice can also be applied to Hugo themes. Hugo is designed for customization and follows a site generation workflow that works a lot like layers in photoshop.
In the above diagram you can see how adding a custom index.html file in the site layouts folder overrides the one in the theme folder. This behavior can be used to change the index.html code without changing the theme code. Customizing the theme CSS styles requires leveraging the layouts folder override.
To modify the CSS you can take advantage of cascading. Here is an example where I override the primary button colour in the Roxo theme.
This diagram shows the basic setup. To override the theme css primary button I've created a file called override.css. This file has to be placed in the theme css folder. The code in the override.css is as follows.
.btn-primary {
background-color: #ff740e;
}
The btn-primary class is used to style buttons on the site. I've changed the button color to the Tangent brand color. One more override is needed to apply this change.
I'll override the head.html file by copying the head.html file from the theme/roxo/layouts/partials folder into a new folder in the site layouts/partials. This new head.html file now overrides the theme head.html. I will add a link to the new override.css file. The code below shows the existing link to the style.css and the new override.css.
{{ $style := resources.Get "scss/style.scss" | resources.ToCSS | minify }}
<link href="{{ $style.Permalink }}" rel="stylesheet" />
{{ $override := resources.Get "css/override.css" }}
<link href="{{ $override.Permalink }}" rel="stylesheet"/>
Because the override.css is linked in after the style.css its styles get precedence, and so the btn-primary background color is applied.
Here is the theme before the change
And with the override.css in place
Hugo themes are easy to add and swap, simply copy or pull the theme files to your site's themes folder and update the config.toml "theme" property to the name of the theme folder.
Themes are tightly coupled to their data schemas, so don't expect that you can take a site with full content and swap it's theme. You may need to port your data to match the new data schema.
Hugo themes are easy to override and build upon without the need to directly change the theme files. The Hugo theme approach is simple yet powerful, it's one of the reasons Hugo is my preferred static site generator.
To host your Hugo based site on Azure for free read how Azure Static Web App Services provide a highly robust and streamlined setup process for static sites.
For more posts on Hugo see:
Photo by Brandi Ibrao on Unsplash