How to Setup a Hugo Website on GitHub
I recently transitioned my blog over to GitHub Pages from WordPress. I was using the free version from WordPress.org and I wanted more granular control over the layout. Additionally, I wanted to automate my blog publishing and social media notifications; the free version of WordPress didn’t meet my needs. So I looked around and eventually fell in love with Hugo! This post outlines how to go about setting up a GitHub Pages website/blog using Hugo.
GitHub
In order to host a website using GitHub Pages you need to first have a GitHub account. You will also need to create two new (empty) repositories.
# The first repository
{your_github_account_name}.github.io
# The second repository
blog
GitHub Pages Repository
In order for GitHub pages to be used you need to have a blank repository that is named {your_github_account_name}.github.io
. In my case, my GitHub account name is currently MSAdministrator so I have a repository named msadministrator.github.io
.
You can find your GitHub account name by looking at your base account profile page. Your account will be https://github.com/{your_github_account_name}.
If I was to go to my repository in GitHub then I would visit https://github.com/MSAdministrator/msadministrator.github.io. You should have the same layout in your GitHub account.
This repository will actually contain our production or live website files. We will configure this in a bit, but once we have everything setup then a visitor could visit https://{your_github_account_name}.github.io to view your GitHub Pages site.
Raw Blog Content Repository
The second repository is called (in my case, but it can be whatever you want to call it) blog
. This repository will contain all the raw files and templates that are used by Hugo to generate your public
facing GitHub Pages site. I will explain this further, but just remember this is where the main “source” of your Hugo site is located and the first repository is where your actual site will exist.
You should now have two repositories setup similar to how mine look (but with your account name).
Now that you have your two empty repositories, let’s go ahead and use Git (or you can download directly from GitHub) and clone the blog
repository locally.
cd ~\_GitHub\
git clone git@github.com:{your_github_account_name}/blog.git
Hugo
Hugo is a framework for building static websites. It utilizes templates and markdown to generate the content for your site. This means, that you can write your blog posts completely in Markdown syntax and Hugo will generate HTML pages for your content. Pretty cool huh?!
The main reason I choose Hugo was that I wanted to write my blogs in Markdown, plus I wanted to have a lot of granular control over all the aspects of my site. Additionally, automation was key!
Let’s go ahead and install Hugo. You can install Hugo using brew
by calling:
brew install hugo
Once you have hugo
installed you can verify that it installed successfully by calling hugo version
.
After we have installed hugo
then let’s go ahead and create a new site. Installing a new site is needed so that we can setup a few of the basic dependencies that we will use later.
# cd into the folder that contains your two repositories you cloned earlier
cd ~\_GitHub\
# create a new site using hugo cli
# and place the new site files in your blog folder (second repository you cloned)
hugo new site blog
Next thing to do is find a hugo template that you like. You can view a complete list of all the hugo themes by visiting https://themes.gohugo.io. For this example, we will use the hello-friend
theme. You can view the Hello Friend
theme here.
In regards to themes, you can have two separate approaches depending on your needs/wants. You can create a Git submodule
for your theme or you can just download your theme and place it in your blog
repository.
A submodule
will be a reference to the original theme location in GitHub. This means that any changes to the creator of the theme will automatically be used/referenced in your website generation. This is great if you don’t plan to make any changes to the theme template, but I like to make changes so I elect to just download the repository and place it manually in my blog
repository.
To add the hello-friend
theme as a submodule
to your repository you would call:
# Inside your blog repository folder call the following git command
git submodule add https://github.com/panr/hugo-theme-hello-friend.git themes/hello-friend
To add the hello-friend
theme as a independent (not a submodule) theme to your repository then you would call:
git clone https://github.com/panr/hugo-theme-hello-friend.git themes/hello-friend
Either of these approaches should create a folder with the name of your theme under the themes
folder. For example, you should now have ~/_GitHub/blog/themes/hello-friend
folder.
Our theme should have a default config.toml
file that you can use (most do). The config.toml
file is a pure site wide configuration file that allows you to specify your base URL, turn settings on and off, etc. Let’s go ahead and copy our themes config.toml
and default example content to our root blog
repository.
# While in ~/_GitHub/blog repository folder we would run the following
cp -r themes/hello-friend/exampleSite/* .
Each config.toml
has different default values or settings, but you can also specify your own (we won’t go into this in this blog post). For the hello-friend
theme the default config.toml
that we copied looks like this:
baseurl = "https://example.org/"
languageCode = "en-us"
title = "Hello Friend"
theme = "hugo-theme-hello-friend"
copyright = ""
paginate = 5
[params]
subtitle = "A simple theme for Hugo"
[menu]
[[menu.main]]
identifier = "about"
name = "About"
url = "/about"
[[menu.main]]
identifier = "showcase"
name = "Showcase"
url = "/showcase"
At a minimum, let’s go ahead and set our baseurl
to our new site address. This will be https://{your_github_account_name}.github.io
. We will also change the title
and a misconfiguration in this template specifically; the theme value
. So in my example, my config.toml
would now look like this:
baseurl = "https://msadministrator.github.io/"
languageCode = "en-us"
title = "MSAdministrator Blog"
theme = "hello-friend"
copyright = ""
paginate = 5
[params]
subtitle = "A simple theme for Hugo"
[menu]
[[menu.main]]
identifier = "about"
name = "About"
url = "/about"
[[menu.main]]
identifier = "showcase"
name = "Showcase"
url = "/showcase"
After we have modified our config.toml
we will also clean up the default archetypes
that we copied earlier. To do this call the following from our blog
repository root folder.
The reason we are cleaning up the archetypes it that the default processing order that hugo takes when generating content. We want to use our themes archetypes and not the default ones in the hugo new site template we did earlier.
rm archetypes/default.md
Now that we have changed our default config.toml
let’s go ahead and tell hugo
to generate a site. We do this by calling hugo
from our blog
repository folder. This will run and it should not return any errors. If it was successful you should have a new folder called public
in your blog
repository. In a bit, we will modify this public
folder but for now let’s test out our website.
# Let's run a local copy of our new generated site
hugo server
You should be told to visit http://localhost:1313/
in your web browser. Go ahead and do this and checkout your new Hugo generated website!
After looking around, let’s shutoff the hugo webserver by pressing crtl+c
in your terminal.
Congratulations, you are now up and running with Hugo
!
Generate GitHub Pages site
So we have not yet touched the first repository we created, our {your_github_account_name}.github.io
repository, but we will now. The first thing to understand is that our blog
repository contains the raw files that are used by hugo
. These files will generate (convert) our markdown and templates into a functioning website. This is what is placed in our public
folder. Currently our public folder has some website files in, but let’s go ahead and remove them now. Don’t worry, we will change this in a bit.
# Remove our public folder from your blog repository
rm -rf public
Now that our old public
folder is removed, we are actually going to begin using our {your_github_account_name}.github.io
repository. But, we are going to make this repository a submodule
of our blog
repository.
A git submodule is typically used in cases when you have a third-party library or dependency within your root project. In our case, a submodule will contain our generated GitHub Pages website files.
To do this, let’s do the following:
# Run the following git command to make our {your_github_account_name}.github.io repository a submodule of our blog repository
# Make sure that you are in the blog folder
git submodule git@github.com:{your_github_account_name}/{your_github_account_name}.github.io.git public
This will clone your {your_github_account_name}.github.io
repository into the public
folder under your blog
repository.
Let’s go ahead and generate our new GitHub Pages website!
hugo server
After running this command you should be able to see that there are now files in our public
folder. This is your new GitHub Pages site!! Congrats!!!
After reviewing our site locally using the hugo server
web server, we should stop the server and let’s push some code to our repositories!
# add our source files to GitHub
git add .
git commit -m 'pushing github pages source files to our repo'
git push
# Now we are going to add our generated github page site to it's repository
cd public/
git add .
git commit -m 'publishing my initial GitHub pages site'
git push
That’s it!!! You’re a GitHub Pages having machine!
After a few minutes, you should now be able to go to your GitHub Pages site by visiting https://{your_github_account_name}.github.io. In my example, it would be this site that you are reading this article on now! Pretty cool huh!?
Bonus Automation
This is cool and all, but let’s add a little shell
script to automate some of this for us when we want to publish a new article. Before we can automate, let’s generate a new post. Each template has it’s own content
types. The hello-friend
template uses a post
content type. To generate a new post
let’s go back to our terminal and run the following:
hugo new post/my-first-post-using-hugo-and-github-pages.md
This will create a new markdown
file in the content/post
folder under your blog
repository. Based on the themes archetypes
it will generate a template markdown file based on the content type. You can view these default archetypes
for our theme under the themes/hello-friend/archetypes/
folder. This theme in particular only has the 1 template, but a lot of themes have multiple archetypes
.
Your new post should have the following at the top of the page:
---
title: "My First Post Using Hugo and Github Pages"
date: 2018-08-26T17:32:37-04:00
draft: true
---
Let’s add some text to this new markdown file as an example. Your markdown file should look like this.
---
title: "My First Post Using Hugo and Github Pages"
date: 2018-08-26T17:32:37-04:00
draft: false
---
# Hello world!!!!
### Welcome to my new GitHub Pages blog
This site was generated using Hugo and is hosted using GitHub Pages. I am hoping to spread my knowledge and expertise through this site in the coming days/weeks.
Now that we have saved this, let’s add some automation in the mix before we proceed. Let’s create a .sh
script to help with this:
#!/bin/bash
echo -e "\033[0;32mDeploying updates to GitHub...\033[0m"
# Build the project.
hugo # if using a theme, replace with `hugo -t <YOURTHEME>`
# Go To Public folder
cd public
# Add changes to git.
git add .
# Commit changes.
msg="rebuilding site `date`"
if [ $# -eq 1 ]
then msg="$1"
fi
git commit -m "$msg"
# Push source and build repos.
git push origin master
# Come Back up to the Project Root
cd ..
After saving this new file as deploy.sh
in our root blog
directory, let’s make it an executable:
chmod +x deploy.sh
Now, all we have to do is call deploy.sh
to generate any new content from our markdown posts and push our code to our GitHub Pages repository.
cd ~/_GitHub/blog
./deploy.sh "adding my first blog post to GitHub pages"
If you add any new markdown files then you should push your blog repository as well.
That’s it! In a few seconds (or a minute or so) you should see your new blog post on your GitHub Pages site! Congratulations!!!! If you have any questions, please do not hesitate to reach out to me on Twitter at @MS_dministrator.