Gatsby to Hugo

I recently decided that I would be moving my personal site from Gatsby to Hugo. I quite enjoyed using Gatsby so I’m not moving due to poor experience but more that I have wanted to give Hugo a try for a while and figured this would be the best project to use it with.

Some cool features of Hugo

  • It’s written in Go! (No Golang programming knowledge required for creating sites with Hugo)
  • It’s lightning fast
  • The list of available themes is huge and you can also roll your own

Starting the move

My site is pretty small and so it shouldn’t be too difficult to move. Both render posts form markdown so there’s no need to do any converting.

Setting up the Hugo site

Installation

brew install hugo
hugo version

If Hugo has installed correctly we should see the following output

Hugo Static Site Generator v0.80.0/extended darwin/amd64 BuildDate: unknown

Create a new site

hugo new site hugo-blog

This will create a Hugo site in the current directory.

Adding a theme

There’s a huge selection of different themes available which can be found on the themes webpage. I have chosen to use the hugo coder theme thanks to the developers over there for a great theme!

To use the theme we need to download it and add it to the themes directory of our site.

cd hugo-blog
git init 
git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder

Now that our theme is in place we can add the following to a config.toml file at the root of our project.

baseurl = "https://www.cameronroberts.dev"
title = "Cameron Roberts"
theme = "hugo-coder"
languagecode = "en"
defaultcontentlanguage = "en"
paginate = 20

pygmentsstyle = "bw"
pygmentscodefences = true
pygmentscodefencesguesssyntax = true

[params]
  author = "Cameron Roberts"
  info = "Software Engineer enjoying all things Cloud and IoT"
  description = "Personal site"
  keywords = "blog,developer,personal"
  avatarurl = "images/icon.jpeg"
  
  footercontent = ""
  hideFooter = true
  hideCredits = true
  hideCopyright = true
  since = 2019

  enableTwemoji = true

  colorScheme = "auto"
  hidecolorschemetoggle = false
  
#  customCSS = ["css/style.css"]
#   customSCSS = ["scss/custom.scss"]
#   customJS = ["js/custom.js"]
[taxonomies]
  category = "categories"
  series = "series"
  tag = "tags"
  author = "authors"

# Social links
[[params.social]]
  name = "Github"
  icon = "fa fa-github fa-2x"
  weight = 1
  url = "https://github.com/cameronldroberts/"
[[params.social]]
  name = "Twitter"
  icon = "fa fa-twitter fa-2x"
  weight = 2
  url = "https://twitter.com/cameron_1010/"
# [[params.social]]
#     name = "LinkedIn"
#     icon = "fa fa-linkedin"
#     weight = 3
#     url = "https://www.linkedin.com/in/johndoe/"
[[params.social]]
    name = "Medium"
    icon = "fa fa-medium"
    weight = 4
    url = "https://medium.com/@cameronldroberts"
[[params.social]]
    name = "Dev.to"
    icon = "fa fa-dev-to"
    weight = 5
    url = "https://dev.to/cameronldroberts"

# Menu links
[[menu.main]]
  name = "About"
  weight = 1
  url = "about/"
  
[[menu.main]]
  name = "Blog"
  weight = 2
  url  = "posts/"
[[menu.main]]
  name = "Contact"
  weight = 3
  url  = "contact/"

You will need to change some values such as social links, avatarUrl, title and anything else that points to my site.

Adding content

Now that we have the plumbing sorted we can start adding some content. If you have an old site you want to bring your content from then you can do that quite easily. The markdown files live in content/posts so you could just copy them over

cp ~/dev/oldwebsite/content/* content/posts/

It’s worth noting that if you are moving content and have also published this to somewhere like dev.to then your canonical URLs may need changing.

On my Gatsby site the posts could be found under /blog like this

https://cameronroberts.dev/blog/consuming-restapi-golang/

whereas on the Hugo site they will be found under /posts like this

https://cameronroberts.dev/posts/consuming-restapi-golang/

This is worth considering if you do have content posted on other sites. I will be doing a post on how we can cross post to other sites soon so stay tuned.

If you don’t have any content to bring over then not to worry as we can quite easily create some

hugo new posts/my-first-post.md

This will generate a file in the content/posts directory that looks like the following

+++ 
draft = true
date = 2021-02-19T23:01:52Z
title = ""
description = ""
slug = ""
authors = []
tags = []
categories = []
externalLink = ""
series = []
+++

I’ll leave you fill that in with whatever you want to write about. It can be anything for now, maybe some Lorem Ipsum.

To summarise our progress so far we have

  • Installed Hugo
  • Generated a Hugo site
  • Added a theme to our site
  • Copied over our old content/added some new content

Now that we have completed these steps we can see our page in action!

Running our site locally

To do this run the following command

hugo serve -D

Hugo will spin up a webserver that builds and serves the site. By default live reload will be enabled which is a great feature as it allows us to see our changes nearly instantly. The -D flag will serve content that is marked as draft which is great for when you are in the process of writing articles but not quite ready to publish.


hugo-blog git:(main) ✗ hugo serve -D                  
Start building sites … 

                   | EN  
-------------------+-----
  Pages            | 48  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  7  
  Processed images |  0  
  Aliases          | 18  
  Sitemaps         |  1  
  Cleaned          |  0  

Built in 138 ms
Watching for changes in /Users/cameronroberts/dev/hugo-blog/{archetypes,content,data,layouts,static,themes}
Watching for config changes in /Users/cameronroberts/dev/hugo-blog/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

If all goes well then your console output should look something like the output above. At this point we can navigate to http://localhost:1313/ and see our site. You may need make a few tweaks here and there where the content is referencing myself or my socials. You may have missed something in the config.toml if so, but a quick find+replace will do the trick.

Push to Github

Now that we have an early version of our site ready it is worth checking this into Github so we can save our progress. It will also need to be in Github for the next steps where we deploy our site to Netlify. The steps to do this are as follows

git init
git add -A
git commit -m "first commit"
git branch -M main
git remote add origin 
git remote add origin https://github.com/cameronldroberts/hugo-blog.git
git push -u origin main

Github usually provides you with the steps when you create a new repo but I’ll include them incase you can’t find them. If you follow the steps above make sure you change the remote origin to your repository. Be sure to know what you’re committing into your repository when using git add -A as you could quite easily check in an API key or sensitive information when using it (should be fine for our first drop of code with the blog). I usually use the VSCode Source control tab as it gives a nice way to compare changes.

Deploying to Netlify

My original Gatsby site was deployed to Netlify and I decided to stick with the platform as it just makes it all so easy. We are going to use Github as this is where I host my code but it is possible to use others such as Bitbucket and GitLab although the steps may deviate slightly.

If you haven’t already got a Netlify account you can sign up here. This will ask you to authorise with Github as it will require access to the repo you want to deploy.

Once you have authorised Netlify navigate to the “sites” page and click the New site from Git button. This will popup a wizard for you to follow to create a new website referencing a Github repo of your choice. Pick the repository that you just pushed your site to. I chose hugo-blog as this is where I pushed my code. The next page will ask for a few bits of information such as Owner and Branch which are usually auto populated with the correct values. In my project they are cameronldroberts's team and main. For the Basic build settings you have two options

option 1) Fill out the required information with your required build command hugo and publish directory public. Depending on the theme used you may need to specify a minimum version build command

option 2) This is the method I have used and would recommend as it doesn’t take much extra effort and everything is all together nicely in your source control. Create the following file in the root of your Github repo in a file called netlify.toml

[build]
publish = "public"
command = "hugo --gc --minify"

[context.production.environment]
HUGO_VERSION = "0.81.0"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"

[context.split1]
command = "hugo --gc --minify --enableGitInfo"

[context.split1.environment]
HUGO_VERSION = "0.81.0"
HUGO_ENV = "production"

[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"

[context.deploy-preview.environment]
HUGO_VERSION = "0.81.0"

[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"

[context.branch-deploy.environment]
HUGO_VERSION = "0.81.0"

[context.next.environment]
HUGO_ENABLEGITINFO = "true"

Just before we deploy our site we need to check this into Github quickly.

git add netlify.toml
git commit -m "Add Netlify config"
git push

Once the config file has reached our Github repo hit Deploy site. Netlify will take a few minutes whilst it gets the site deployed but once it has you should get a site link on your Site overview page. Visit the page and tadaah you have deployed your site to Netlify and the world can see.

Some debugging tips if it doesn’t quite go to plan

  • Check the Netlify logs it will usually point out the errors it is struggling with
  • If you chose option 1 and didn’t use the Netlify config file then make sure you are using at least the minimum version of Hugo that your theme requires

Custom domain

Whilst the urls generated by Netlify are completely free and great whilst in dev, if you’re creating a proper site I would imagine that you would like to add your own. You can buy a domain through Netlify and by doing this they will configure DNS and provision a wildcard certificate. I bought my domain prior to making the original site so never got one through Netlify. I can imagine this would be the easiest way to add a custom domain to a Netlify site but it isn’t too difficult to do so when your domain is purchased elsewhere. You also have the option to use the Netlify DNS and let them handle everything. I think this may be slightly out of scope for this post but if you want to read up on how you can do it then this document is good place to start

If you don’t mind a domain that ends with netlify.app then you can change the randomly generated name to something more suitable. Head over to Site settings -> Domain Management and click on the options drop down under Custom domains.

web.dev/measure

Google have provided a pretty cool site which you can use to measure overall performance of your site. I ran both sites through the tool and got the following reports

HugoScoreGatsbyScore
Performance99Performance92
Accessibility100Accessibility97
Best Practices100Best Practices100
SEO100SEO100

According to the tool the Hugo site outperforms the Gatsby one. In defence of the Gatsby site there’s a few bits of code in there that I have written to test things out and never finished them or have a few TODO items left so it may not be completely fair race. Having said that the Gatsby site despite being slightly neglected is not performing too badly.

Thanks for reading and I hope you enjoyed the post!

https://www.cameronroberts.dev/

Reading list