Well, I learned how to make a Hugo SSG theme backwards. I hope from what I have learned, this could be a good simple guide to get started. Themes are good to realize what files in your projects are necessary for templating or default states.

1 - Start your project

To start a project, run the command hugo new site {site name} from the terminal. For example, I could execute this command as hugo new site demo-theme-site. Use the command cd demo-theme-site to go into the root of the project.

Be sure to fill your project with some content, so that you can actually see what changes are being done. The content that you’ll create will go into Hugo’s /content folder. Refer to this section in order to create some content.

2 - Create the theme

The command to create a new theme is hugo new theme {theme name}. Run that command from within the root of your Hugo project. This command will insert a boilerplate theme into the themes folder of your hugo project. For example, I would run hugo new theme demo-theme.

As of Hugo v0.65.2, the file structure that gets inserted is as follows.

- theme.toml
- /archetypes
    - default.md
- /layouts
    - /_default
        - baseof.html
        - list.html
        - single.html
    - /partials
        - footer.html
        - head.html
        - header.html
    - 404.html
    - index.html
- /static
    - /css
    - /js

In the LICENSE file you may change it for your name, or delete the file.

In the theme.toml file, that contains the metadata for your theme. Fill out appropriately.

The /archetypes/default.md file contains the default starting format for your content files. I typically favor the theme archetype over the site archetype. Keep all the the templating or default files with in the theme. So for the Hugo archetype lookup order to default to the theme’s archetype, remove the site’s archetype folder.

The layouts contain all the templating files for the website. These are going to be very useful. Fill them out as needed. Refer to the templating documentation to make your own templates. For a basic templating layout, the files provided are good to start with.

Styling and Scripting

Now here is where the real theming is. I am going to explain what I did to approach theming. You can follow my example or make some variation of it as you like.

In the root of the theme, I made in a node project with npm init -y. I installed Rollup for the script build and PostCSS for my styling build. I decided on Rollup, because I didn’t want so much overhead for my script files. And I decided on PostCSS for some modern CSS features. Here is the file for my script process, and here is the file for my style process. I put all my styling and scripting files within the a /src folder.

The build process for the scripts and styles will be located in the package.json file. Note, I have all the build files going to the assets/ folder. For Hugo, that folder is meant to be accessible during the Hugo build process. In any template file that Hugo has, you can access any file within the assets/ folder and submit the file through a processing pipeline. See Atomic Duck’s script footer template to see how I use the assets/ folder in order to process the script files of the theme. The processes that I like to do with files is put them through a minifier for performance optimization and a fingerprint hash to redo any cache automatically with new deploys.

A thing to note here for my styling process, I made it so that the user of theme has to insert their own colors with CSS variables. So in the site project’s assets/css/ folder, the user puts a vars.css file. Check out the readme file for the instructions on the CSS variables.


So there, I hope that was simple enough. Granted, this may have been written with the idea that one is familiar with how Hugo works. Make your own theme! It’s actually a fairly cool thing to do.


My Atomic Duck theme

Hugo Getting Started