Featured image of post Hugo Website Guide: Theme Setup & GitHub Configuration

Hugo Website Guide: Theme Setup & GitHub Configuration

Discover how to kickstart your Hugo website with theme selection, GitHub setup, and seamless integration.


I describe here how to start a new Hugo website properly. From the choice of the theme, how to create and configure the GitHub repositories, and add the theme to your Hugo website, this article aims to give you all the keys to start your website in the best condition.


❯  Prerequisites

I suppose here that you are familiar with Git and that you are using GitHub to host your code.

You now have to install Hugo locally. Since the installation method differs depending on your operating system, I invite you to have a look at the documentation. But to keep it short, you can install it on MacOS via homebrew:

1
brew install hugo

On (the majority of) Linux OS, via snap:

1
sudo snap install hugo

And for Windows OS, via winget:

1
winget install Hugo.Hugo.Extended

❯  Choose, and configure your website’s theme

A website using Hugo imperatively needs a theme to work. Among the hundreds of themes available here, I finally chose the theme Stack: simple, elegant, modern, with a light & dark mode, this is also a theme regularly updated by his author, Jimmy Cai, with an active community, and also lots of GitHub stars.

You can also have a look at the demo website to see what it looks like.

I will assume that you also have chosen this theme in the rest of this guide. If your choice is different, you may need to adapt the following steps to yours choices.


❯  A public or a private repository?

In the first step to create a Hugo website, directly referencing the author’s theme repository is extremely convenient. Furthermore, after one or two articles you will probably be tempted to customize some elements of the theme. And even if you can override components of the theme by overriding some components directly on your website, it is generally cleaner to directly edit the theme. I recommend then investing some extra time now to create a personal copy of the theme, either in forking it (that leads you to have a public repository) or in using an alternative method to create a private repository, that allows you to continue to update your theme with the latest update applied in the theme by their author.

If you want to use the author’s theme directly, simply skip this part.


❯  A public repository? Fork the theme

This is the easiest way! From the GitHub repository of the theme, click on fork. Then choose the name you want to give to the forked theme:

button "fork" on the hugo-theme-stack github repository
button "fork" on the hugo-theme-stack github repository
the screen displayed after a click on the button
the screen displayed after a click on the button

That’s all. You have your copy of the theme. You can then clone-it locally:

1
git clone git@github.com:letrome/stack

❯  Configure the upstream to apply future updates on the theme

Unless there have been no updates to the theme you have chosen for a long time (in which case I strongly recommend that you choose another theme that is regularly updated), you will probably have to apply new updates to the theme you have forked from time to time. There are several ways of doing this ( see the documentation on this subject).


❯  From the web UI

From the web UI, on the repository of the theme you have forked, click on the button “Sync fork”.

Sync fork from the web UI
Sync fork from the web UI

❯  From the command line

First, from the repository you have cloned locally, fetch the branches and their respective commits from the upstream repository:

1
git fetch upstream

Then, checkout your local default branch (generally named "main", or "master"):

1
git checkout main

Finally, merge changes from the upstream default branch to your default branch:

1
git merge upstream/main

Depending on the situation, you may have to resolve conflicts. Once done, apply changes to your remote repository:

1
git push origin main

Note that you can also apply the update using the GitHub CLI ( cf the documentation). I won’t detail here this solution since I have not tried it myself.


❯  A private repository? A solution with –bare and –mirror

On GitHub, forked repositories are necessarily public. But you can have private repositories with the same possibilities of update of the changes that have been made on the original repository in applying the following ( cf this super guide on this topic).

First, clone the repository you want to fork in using the option --bare:

1
git clone --bare git@github.com:CaiJimmy/hugo-theme-stack.git

Then, create the private repository on which you want to add your private fork from the GitHub web UI. Suppose you named it “stack”. Then, you will now mirror-push your clone to your new repository

1
2
cd hugo-theme-stack.git
git push --mirror git@github.com:<your_username>/stack.git

At this step, your bare repository previously created is no longer interesting, and you can simply delete it.
Now, clone the repository containing the forked theme:

1
git clone git@github.com:<your_username>/stack.git

To be able to receive future updates applied on the original repository, add it as remote (named upstream):

1
2
git remote add upstream git@github.com:CaiJimmy/hugo-theme-stack.git
git remote set-url --push upstream DISABLE

Finally, similarly to the last steps described in the section concerning the public fork, apply updates from the original repository:

1
2
3
git fetch upstream
git rebase upstream/main
git push origin main

❯  The website’s repository

Now, we will consider your website’s repository, on which you will put your configuration to detail how your website works, and which functionalities you want to enable. In particular, this is where you will put your website’s content (like the pages or posts for example).


❯  Again… public, or private?

Similarly to the question you asked before for your theme, you have to decide if you want to make your website repository public or private. On the advantages of having a public repository, you can use GitHub pages to deploy your website. This is truly straightforward and you can have a website up and running in a few minutes from the beginning of the repository. The direct drawback is that the whole website’s codebase is publicly accessible … not always the right solution, in particular, if you want to restrict access to some part of your website, or if you have some internal configuration that you want to limit the exposure.

On the other hand, everything is still possible with a private repository, except that you have to choose another solution than GitHub actions for your website’s deployment. I strongly recommend using Netlify, which offers to host your website for free (with a few limitations such as a limited number of users, the impossibility of running several deployment tasks in parallel, or a limit of 300 minutes of build time per month. However, for personal use, this should not limit you).

Note that regardless you choose to have a public or private repository, this will not change the initialization of your repository.


❯  Initialization of the repository


❯  Option 1. Start your repository from scratch

This is not the method I recommend to you to start your website, in particular, if this is the first website on Hugo that you are creating.

First, create a new repository from GitHub’s web UI.

"New repository" button on the GitHub web UI
"New repository" button on the GitHub web UI

Then, on the new screen, type the name of your repository, if you want to make your repository public or private, and a few other configurations like adding a readme file, a gitignore file, …

The screen to configure the new repository
The screen to configure the new repository

Once created, clone the repository locally. Then, from the repository, type the following command to initiate your website Hugo, and to add the theme you have created on the previous section as a git submodule, cf the Hugo Quick start documentation :

1
2
3
4
hugo new site .
git init # optional if you have created your GitHub repository, and cloned it locally. Necessary otherwise to add the submodule
git submodule add git@github.com:<your_username>/stack.git themes/stack
echo "theme = 'stack'" >> hugo.toml

Now, by running hugo server from your repository, it should create your website’s resources in a folder named “public”, and launching a server to serve it. By visiting the address http://localhost:1313, you now have access to your freshly created website:

What a Hugo stack website started from scratch looks like
What a Hugo stack website started from scratch looks like

Quite empty, isn’t it? At this point, I recommend you to have a look on the documentation and resources relative to the theme. Applied to the theme hugo-theme-stack, you can have a look here.

You can also add some resources, generally available on a folder named “exampleSite” on the repository, containing mock articles. If you copy the content of the exampleSite into the website repository, you now obtain the following result:

The same website, after having copied the content of the "exampleSite"
The same website, after having copied the content of the "exampleSite"

It is not perfect yet, with a few broken images. But, still, a good playground to start to build your website.


❯  Option 2. Using the theme starter

If your theme offers such functionality, this is the easiest way to start a new Hugo website. The author of the hugo-theme-stack theme provides a repository that you can use as a template to start your website: https://github.com/CaiJimmy/hugo-theme-stack-starter.

From the repository, you can click on Use this template > Create a new repository, to create a repository containing a blank Hugo website, with the author’s theme already configured. If you clone this repository locally and run the server via hugo server, the website available locally at the address http://localhost:1313 looks like this:

What a website created from hugo-theme-stack-starter looks like
What a website created from hugo-theme-stack-starter looks like

Magic right? If you are ok with directly using the author’s theme, and you will never have to customize it to adapt it to your needs, the bootstrap of your website is now over.

Otherwise, it means that you have previously created a fork of the theme, public or private. I will now detail some extra steps to use your fork instead of the original theme. There are 2 different manners of adding a theme to your website:

  • The first one is in using git submodules, which is the method presented in the Hugo documentation, and that I have also shared in the * *Option 1. Start your repository from scratch**. This is also, for the anecdote, the solution I have chosen for my website.
  • The second, the one chosen by the author of hugo-theme-stack, is in using the Hugo modules.

❯  Before adding the theme: do some cleanup

First, on the theme’s repository, remove the file go.mod. Then, on the website’s repository, remove the files go.mod, go.sum and config/_default/module.toml.


❯  via git submodule

Choosing the git submodule offers some advantages over using go modules. First, this is easier to configure. Then, you can modify both the content of your website and the theme itself from the same repository.

Adding the theme as a submodule is quite straightforward. From the website’s repository, simply add the submodule as follows:

1
2
git submodule add git@github.com:<your_username>/stack.git themes/stack
echo "theme = 'stack'" >> hugo.toml

That’s all! Simply verify that your site is working as expected in running hugo server locally!


❯  via Hugo modules

Choosing (Hu)go modules, on the other hand, give some advantages compared to the git submodules. In particular, as Hugo is mainly developed in Go, you remain in the same ecosystem.

Also, it allows you to configure accurately the versioning of your theme, in defining tags for some specific version on the theme repository, and in declaring explicitly which tag you want to use on your project.

For a complete guide about the Hugo modules, and in particular, how to include a theme as a Hugo module, you can have a look at the documentation.

From the theme repository, type the following command:

1
2
3
hugo mod init github.com/<your_username>/hugo-theme-stack-starter
go get -u github.com/<your_username>/stack
echo "[[imports]]\npath = \"github.com/<your_username>/stack\"" >> config/_default/module.toml

check that it works with:

1
hugo server

By default, it will download the last tag available. To create a tag, on the theme repository, add a tag (git tag vXXX ; git push --tag).

Then, from the website’s repository, go get -u github.com/<your_username>/stack retrieves by default the most recent tag; You can also specify a specific tag by suffixing the address of the module in the go get command by @<targeted_version>. For example, to get the tag v1.0.0:

1
go get -u github.com/<your_username>/stack@v1.0.0

In addition to downloading this version if not already the case, it will also update the version in the file go.mod.

You probably noticed that contrary to when you add the theme via git submodule, the module is not directly added to your website repository. This is added either at the location defined in the variable $GOPATH, or, if this variable is not set, by default to the user’s home repository (typically the folder ~/go).


❯  Conclusion

I have detailed in this article how to set up your website and add the theme that suits your needs. In particular, how to create a fork of the theme, either public or private, that allows you to update it to suit your needs, or to customize it. At this point, you should have a good first working version, ready to be deployed on your favorite platform (GitHub pages for example, if you choose a public repository; Netlify, probably the most popular solution to deploy your Hugo website; other alternatives like Heroku or Vercel; or even hosting it on an EC2 instance or at home on your Raspberry, …).


❯  References