Many moons ago I built my personal site using Hugo, a static site generator written in Go. I've had some people inquire about the design of my site since then. Some have even asked for permission to use it. Because of this, I've decided to turn the entire website into one Hugo theme. Here's a link to the theme's directory if you're curious.
I'm going to make this short and sweet. I will also make the assumption that you are familiar with Hugo and you already have a working site. Let's dive in.
The first thing to understand is that traditional Hugo sites and Hugo themes are
not that different from each other. The only difference is where the code lives,
either in the main project directory (i.e., the root of your project), or the
git submodule add https://github.com/username/test-theme.git themes/test-theme
This installs a theme named
test-theme into the
The above command illustrates where a theme should live: in the
directory. This is helpful information for us later, but for now we are going to
shift focus to setting up a development environment that will allows us to build
the theme and test the theme at the same time.
There are a few ways to go about this. I'm going to explain the way I chose:
- Create a new project directory to store your theme
- Copy all content from original website directory to new directory
- Re-init theme folder with git
- Create a
Steps 1 and 2 should result in a duplication of your website folder.
Step 3 should start you off with a fresh git history.
Step 4 adds a new file to the mix -
theme.toml. This file is crucial to your
theme and needs to be populated with the right content. You can
refer to Hugo's documentation on
for what should go in this file.
At this point, the new theme directory should look just like your old website
directory, save for a new
theme.toml file and a fresh git history.
Once the 4 steps above are completed, we can move on to creating our example site. The example site is useful because it will let you test your theme in the browser as if you were a user of the theme.
exampleSite directory at the root of your theme directory. The only
mandatory file in this directory is a
config.toml. Hugo uses it to locate the
theme you want to use for the example site.
theme = "name-of-your-theme-directory"
themesDir = "../../"
theme key should be the name of your theme's directory. The
tells Hugo where to look for the theme directory. It will essentially
concatenate the values of both keys and look for your theme at
You can run the example site using:
hugo server -D
This should start your example site in the browser using your theme.
The Hugo team has a GitHub repository named HugoBasicExample that provides the "default content" used for all theme demos, however there are cases where your theme does not align with the assumptions HugoBasicExample makes.
In these cases the Hugo team can whitelist your theme so that it demos the
contents of your
exampleSite directory instead. This was my case, but it may
not be yours.
For this to work, you'll need to have an
exampleSite/content directory with
example content that will showcase your theme in action. Check the
repository for more information.
I would suggest having at least one piece of content for each content type.
This step goes hand-in-hand with the one above. You'll need to decouple your theme from you. This is very much a solo step, as your site could be heavily coupled to you as an individual. So your mileage may vary here. Some gotchas might include:
- header text
- social icons/links
- email addresses
- about page
My suggestion would be to go through every page in your theme and do a heavy analysis on what is crucial to the functionality and what is not. What needs to be abstracted away into configuration and what can stay.
This was the longest part of the process for me. It brought up some valid questions about how the website was built, it forced me to adjust some pages so that they can be configured easily, and it even made me think about some constraints I wanted to have with my theme.
When this step is finished your website should be completely decoupled from your content and you are ready to submit your theme for review.
This is a very straightforward step. The Hugo team has a repository named hugoThemes that manages all of the official themes available. In order to submit yours you'll need to:
- Push your theme repository to GitHub
- Make sure your theme meets these requirements
Step 2 includes a few administrative tasks not mentioned in this post, like
getting theme screenshots and detailing a
Once the steps above are complete you can go to the hugoThemes repository and file an issue for your theme, which is the standard process for submitting your theme for approval.
And that's it! The team at Hugo didn't take long to help me align my theme and get it up on the official themes list. Here are a few links that might help you with context:
- My Hugo theme repository
- The issue I filed to submit my theme
- The official list of Hugo Themes
- The hugoThemes directory
Please reach out on Twitter if you have any questions!