Blog with Hugo and Github

Share on:

As it is customary, my first post is about building this website. This post assumes that you have a basic understanding of git, GitHub, and web domains. The focus will be on the tools chosen and integration of these tools to build a static website.

Goals

  • Write content in your favorite text editor
  • Manage content in source control (git)
  • Automate deployment of the content to the website
  • Privacy and security of website visitors

Quick tools summary:

Hugo

Hugo is a static site generation tool written in Go. Hugo has strong theme support and a variety of themes.

Features that matter to me:

  • Incremental build - Site generation is incremental and blazing fast
  • Powerful template support - Go templates
  • Privacy compliance - GDPR
  • Explicit security model - Security

A full feature list is available here.

There are many static site generators out there, here is a comparison:

Comparisons with other static site generators

Feature Zola Cobalt Hugo Pelican
Single binary yes yes yes no
Language Rust Rust Go Python
Syntax highlighting yes yes yes yes
Sass compilation yes yes yes yes
Assets co-location yes yes yes yes
Multilingual site ehh no yes yes
Image processing yes no yes yes
Powerful template engine yes yes yes yes
Themes yes no yes yes
Shortcodes yes no yes yes
Internal links yes no yes yes
Link checker yes no no yes
Table of contents yes no yes yes
Automatic header anchors yes no yes yes
Aliases yes no yes yes
Pagination yes no yes yes
Custom taxonomies yes no yes no
Search yes no no yes
Data files yes yes yes no
LiveReload yes no yes yes
Netlify support yes no yes no
Vercel support yes no yes yes
Breadcrumbs yes no no yes
Custom output formats no no yes no

Source: zola

Hugo's single binary and Go module based extension mechanism makes it simpler to deploy and integrate it into the gitops based workflow.

Install Hugo

1brew update && brew install Hugo

Pick a theme

To jump-start, your website, select a theme that suits your needs. After reviewing a ton of Hugo themes and experimenting with a few, I finally settled on hugo-clarity. A huge shout out to Chip Zoller and Dan Weru for this awesome theme. Design is clean with no clutter what so ever, and has all the features required for a technical blog. I particularly love the superb rich code block functionality.

There are many ways to install a theme, but I prefer the cool go mod approach:

1hugo new site yourSiteName
2cd yourSiteName
3git init
4hugo mod init yourSiteName

NOTE: You will need the latest Hugo binary and Go installed on the system for this method.

Configure the theme

Most themes provide an exampleSite, copy it over to your root directory, and edit the config.toml. You can find the config.toml for this site here.

1cd yourSiteName
2git clone https://github.com/chipzoller/hugo-clarity /tmp/hugo-clarity
3cp -a /tmp/hugo-clarity/exampleSite/* .
4rm -rf /tmo/hugo-clarity

Customize logo and icon

Create a simple logo and favicon for the website. There are many free to use icons available at flaticon.com. I used draw.io to create the logo and the icons and this favicon generator to generate the website's icons. Unpack the icons into the static folder.

Local testing

Hugo comes with a built-in server that you can use to test your website live:

1# Serve the files, including draft posts
2hugo server -D

To generate the site:

1# Generate content including drafts
2hugo -D

The above command generates the full static content in the public folder, which can be copied to your webserver.

Github

Create a new empty repository on github for your website and push your content.

1cd yourSiteName
2# Make sure you configured your .gitignore correctly to ignore the addition of
3# unnecessary files.
4git add .
5git commit -s -m "commit comment here"
6git remote add origin "https://github.com/yourUserName/yourSiteName.git"
7git checkout -b initial-commit
8git push origin +initial-commit

Actions and checks

Github support actions to define your deployment workflows. I strongly recommend adding merge checks for your content for the following:

  • Hyperlink Check
 1# .github/workflows/check-md-links.yml
 2name: Check Markdown links
 3
 4on: push
 5
 6jobs:
 7  markdown-link-check:
 8    runs-on: ubuntu-latest
 9    steps:
10      - uses: actions/checkout@master
11      - uses: gaurav-nelson/github-action-markdown-link-check@v1
12        with:
13          use-quiet-mode: "yes"
14          use-verbose-mode: "yes"
  • Spelling Check
 1# .github/workflows/spell-check.yml
 2name: Spellcheck Action
 3on: push
 4
 5jobs:
 6  build:
 7    name: Spellcheck
 8    runs-on: ubuntu-latest
 9    steps:
10    - uses: actions/checkout@master
11    - uses: rojopolis/spellcheck-github-actions@0.5.0
12      name: Spellcheck

To enable the checks, go to GitHub repository settings -> Branches. Add a branch protect rule for your main branch and enable the following checks:

Github Checks

Hosting

When I started, I considered using github.io to host the website, looking a bit further I found vercel and render. Both of them offer static website hosting for free, with the upside of hosting APIs if you add services to your website. In the end, vercel's cli support sealed the deal.

  1. Create an account using your Github account
  2. Integrate with GitHub and allow access to your blog repo
  3. Vercel app will listen for all changes to Github repo and perform deployment

Vercel supports staging and production deployments. Setup the main branch as the production branch. Render your content by pushing it to the main branch. To avoid accidental rendering, add the vercel check to the main branch, as shown in the GitHub section. Vercel Github integration will automatically do a staging deployment for all pull requests. You can verify the staging deployment before merging to production branch.

Custom Domains

If you have a custom domain like me, you need to set up a forwarding record with your domain provider. Please note that you need to use the CNAME record for sub-domains like webbook.chamarthy.dev. For more details on configuring custom domains with vercel, refer to the documentation.

Blog Workflow

Once you completed the above steps, you can focus on writing. The following is my workflow:

  • Create a branch for your post
1git checkout -b drafts/building-webbook
  • Create a new post
1hugo new post/2020-12/building-webbook.md
1git add .
2git commit -s -m "blog: building webbook"
3git push origin +drafts/building-webbook
  • Create a pull request to the main branch
  • Github actions will take over and give you a blessing to merge
  • Rebase and Merge to the main branch
  • On merge, vercel application will build the website using Hugo and deploy to your website.
  • Check your website for the new content

Summary

With this workflow, you can focus on your writing and enjoy a familiar workflow to manage and publish content to your website.