Using Hugo with Github Pages

September 19, 2018

So, I decided to start using Hugo as the platform for my website/blog. I’ve looked into different options, including Jekyll and Hexo and in the end, Hugo is the one that made the most sense to me.

I also wanted to use Github Pages with it, including using a custom domain and using HTTPS by default. Had I chosen Jekyll, integration with Github Pages would have been automatic. However, Github Pages do not directly support any other static website generator. But I wanted to use Hugo.

And sure enough, there are some instructions to do just that on the Hugo website. However, I didn’t particularly like any of the options. I wanted something that would work the same way and equally well for user pages, organization pages and project pages. And I wanted to automate most of the process, I didn’t want to think about how it works when I just want to update my website. I also wanted to easily duplicate the setup to other projects.

Since the only option available in Github Pages that works for user pages, organization pages as well as project pages is to publish your website directly from the master branch, that’s the option that I had to choose. So, the idea is to have the Hugo source files and create the content in a source git branch and then publish the files that are generated by Hugo to the master branch.

The directory structure for a Hugo project looks something like this:

├── archetypes
├── config.toml
├── content
├── data
├── layouts
├── public  <---- Generated files go here
├── static
└── themes

Hugo puts the generated files inside the public directory. What I wanted to do was to have the entire site directory mapped to the source git branch, except the public directory, which should be mapped to the master branch. Here’s how I did it…

First, create a new repository in your github account. Don’t add a README file or anything else at this step, we’ll do that later.

Then, create a new Hugo site locally with:

hugo new site newsite

Feel free to change the “newsite” name to anything you want.

Then, move into that directory you just created, create an empty text file with Makefile as the filename and put the following contents in it:


	rm -rf public
	mkdir public
	git worktree prune
	rm -rf .git/worktrees/public/
	git worktree add -B master public origin/master
	rm -rf public/*

publish: build
	cd public && \
	git add --all && \
	git commit -m "Publish on `date`" && \
	git push -u origin master

	hugo serve --watch

	git init
	git add 
	git commit -m "first commit"
	git remote add origin ${GITREPO}
	git push -u origin master
	git branch source
	git checkout source
	git rm
	git add ./*
	echo "public" > .gitignore
	git add .gitignore
	git commit -m "Add hugo files"
	git push -u origin source

Make sure your edit the GITREPO variable at the top of the file to match the address of the git repo you created on github.

So, now we’ll add the Makefile and all files that were generated by Hugo. Open a terminal in the same directory you just put the Makefile in and run:

make init

That does all the work of setting up the repo with the structure that we want to have. It also adds an empty file in the master branch. You can edit that to provide a description for your project.

Pick a theme from and set it up. I’ll use the Black & Light theme for this example:

git submodule add themes/black-and-light
cp themes/black-and-light/exampleSite/config.toml ./

and edit the config.toml file with your details. You can then create some content:

hugo new posts/

And that’s mostly it… You’ll be working on your content in the source branch and publishing your website to the master branch. Don’t forget to go into your project’s Settings page in Github and then in the Github Pages section, select master branch as the source.

Updating the website with new content should be simple enough. To build the project, just run:


and to publish the changes to your site, run

make publish

You may also run:

make serve

which is just a shortcut for hugo serve --watch for testing your changes locally.

In order to clone the repo on another PC, go straight to the source branch and also clone the theme at the same time, you can run:

git clone -b source --recurse-submodules