This post goes over how and why I transitioned from GitHub Pages to Netlify and Hugo for my personal blog
I had a personal site built with Hexo.js and Github Pages + Google Domains. It was working pretty well for a developer’s personal site tbh but I hadn’t posted to it in a long time. The last commit to the repo was November 2018. Over the course of 2019 I’d focused primarily on posting articles to the Employbl Blog (my side project) and the Employbl Medium publication. Over the past six months or so I’ve become more interested in Netlify and the whole serverless and “jamstack” world, so on a whim I nuked my old site in favor of a template placeholder. As a sit here writing this article my personal website is currently an ad for a non-existent coffee company:
In this post I’ll outline why I picked Netlify, the alternatives and how I
got my groove back built and deployed a new website to replace my old one.
Over the course of 2019 even though I didn’t make a single update to the site or post a single article traffic hovered around two to three thousand pageviews per month. Below is a Google Analytics snapshot of site traffic for connorleech.info:
This amount of traffic is non-trivial for me. My side project Employbl gets about four to five thousand pageviews a month. What I’d like to do is have the technical blog posts live on Employbl to build traffic there and maybe have links pointing to it from my personal site. The current links to my personal site (email verification, AWS, quick admin panel etc) are all broken because I deployed the coffee company site ☕and it really nuked everything. So I want to fix these links, point them to Employbl articles and have a simple personal site where I can post about music, parenting, cooking, whatever.
To accomplish this I really could have made updates to the Hexo site and used it for future posts as is. I wasn’t a big fan of Hexo even when I was first building it but it seemed like the best option at the time. There’s totally cool stuff that you can do but it used Require.js, Bower and Jade templates. I hadn’t touched it in over a year so I would have to re-familiarize myself with the project and that didn’t excite me too much.. Meanwhile, Netlify offers all sorts of cool features like default HTTPS support (which I didn’t have) and services to invoke AWS Lambda functions, easy deployments and services for adding forms and authentication down the line. They even have Content Management System (CMS) support if I wanted to go that route. Ideally in this transition I can make it easier and more enjoyable to publish articles, leading me to update the site more frequently, write more and grow traffic to the site. 🤞
The workflow was writing articles in markdown, committing them in Git and then pushing up to a repo. Running the
hexo deploy command would build and compile the assets and markdown articles and push it up to a new Github repo that served as the live site on my http://connorleech.info domain. I’m keeping the source code for these projects up on Github here and here in case you want to check out the code and how it worked. The theme is called Computer Lab built by an agency in NYC a few years ago. Overall my personal site worked pretty well but I didn’t publish posts to it very often.
There are tons of options about where and how to host your site. I chose Netlify because the first time I used it the HTTPS support and quick dev and deployment cycles really blew my mind. There are definitely trade offs though. Netlify specializes in static sites, meaning you don’t have your own server running on their hardware. Blog posts are written in markdown and compiled on deployment without you hosting a server or database. You could also use a service like Contentful with Netlify to host your content in the cloud. To do things like form submissions and writes to a database it’s probably best to use serverless functions or the value-add services Netlify offers like Netlify Forms and Netlify Functions (which serve as a convenience wrapper around AWS Lambda). If I need a backend on top of the Netlify site I make I might use something like the Serverless Framework to talk to a database. Once you’ve chosen to build a site with Netlify you’ll need to choose a static site framework or build with plain old HTML and CSS. Netlify has a page with lots of JAMstack templates to choose from. That’s where I found the coffee placeholder site.
To learn more about the JAMstack, what it is and how to use it, I recommend reading or browsing through this O’Reily Media + Netlify free book that breaks everything down about “Modern Web Development on the JAMstack”.
There are hundreds of great options for hosting a blog online. You can use no code solutions like Wordpress, Medium, Wix or Squarespace. You could also go the opposite route and build a blog from scratch using an MVC framework like Laravel, Ruby On Rails, Django or Node.js. There more middle of the road solutions like Statamic and Ghost that are built with developers in mind but don’t require much coding to get up and running. Netlify also has more direct competitors in the static web hosting space like ZEIT or hosting a website on an AWS S3 bucket. What you choose is a matter of personal preference but there are no shortage of options. I think what’s important is to not get analysis paralysis, pick one, launch it and start writing.
For the Employbl blog I added Laravel Nova administrator tool on top of it since Employbl is built out of Laravel 5. Adding a markdown blog was pretty easy given that I already had the server deployed on Laravel Forge with a MySQL database. Shoutout to Nick Basille of Lambda School for the awesome getting started with Laravel Nova blog post, available here. I wanted to explore Netlify and static site hosting so I decided on Netlify and here we go….
It wasn’t my first rodeo with Netlify. I’d previously written about how to set up a Netlify site with Gatsbyjs on the Employbl blog and even tried unsuccessfully to connect it to a FaunaDB database. When I nuked the Hexo site in favor of the placeholder coffee site I proved that it was easy to manage DNS config and the deployment process (something I was worried about). The domain connorleech.info I bought through Google Domains now points to Netlify’s servers instead of the Github Pages servers it previously pointed to.
To switch my Google Domains DNS record from Github Pages to Netlify I created a new Netlify site that by default got a Netlify domain, in my case https://connorleech.netlify.com/. Then I added some custom domains to the project in the Netlify dashboard:
For more info on how to do this be sure to check out Netlify’s docs on custom domains. After updating the custom domains section of the Netlify dashboard I added “custom name servers” in the Google Domains dashboard:
Now I had my domain connorleech.info pointing to a Netlify site. I hadn’t installed any Google Analytics tracking on the site so that’s why all my traffic went to zero (this was middle of October 2019). There was no traffic but the site had HTTPS/SSL support, which is generally better for SEO than plain old HTTP domains. The site worked if people typed in www.connorleech.info or connorleech.info. The website was set up but I still need to code and launch something real, as well as provide pages for the previous links I had so there aren’t a bunch of broken links out there on the internets.
Large community (40k+ stars on GitHub)
Works well with Netlify (in their ebook they outlined the Smashing Mag case study, so seems legit)
Built with Go. I’ve never programmed in Go but all the cool kids these days seem to be using it. Plus I don’t think I’ll have to actually be writing too much Go. We’ll find out..
Themes. Themes are rad. There’s one that looks good called Goa it’s super minimal so hopefully hard to screw up. It has tags and categories for posts and was last committed to yesterday. Seems good enough for me.
Built with Go: I’ve never programmed in Go.
Customization: Maybe if I want to build a registration system or do something crazy customization might be more difficult than using JS or PHP with which I’m familiar. For my personal site though I just want content and my personal info on there. Not too worried for now about adding extra features. It actually could be a good thing having this barrier. The web property I really want to grow is Employbl.com so I’ll save my crazy dev stuff for that and keep my personal site for content instead of extra coding. Plus, I’m sure I could figure it out if I really need to add stuff… (said every developer ever…)
Following the docs at Hugo Quickstart. They have a mac installer, that’s cool!
$ brew install hugo
waiting for brew install to finish..
$ hugo --help hugo is the main command, used to build your Hugo site. Hugo is a Fast and Flexible Static Site Generator built with love by spf13 and friends in Go. Complete documentation is available at http://gohugo.io/. Usage: hugo [flags] hugo [command] Available Commands: check Contains some verification checks config Print the site configuration convert Convert your content to different formats deploy Deploy your site to a Cloud provider. env Print Hugo version and environment info gen A collection of several useful generators. help Help about any command import Import your site from others. list Listing out various types of content mod Various Hugo Modules helpers. new Create new content for your site server A high performance webserver version Print the version number of Hugo
To install a site with the Hugo theme Anake theme and specify you want your site to use that theme is:
$ hugo new site connorleech.info $ cd connorleech.info $ git init && git submodule add https://github.com/budparr/gohugo-theme-ananke.git themes/ananke $ echo 'theme = "ananke"' >> config.toml
There is only one config file:
config.toml, which is really nice. No need for package.json and webpack, eslint etc. Start the server with:
$ hugo server -D
Your site is now running locally on http://localhost:1313/
This is the config I’m using to update the URL so instead of
/posts/ it goes to
/blog/. That way my URLs won’t break.
baseURL = "https://connorleech.info/" languageCode = "en-us" title = "Connor Leech" theme = "ananke" [permalinks] posts = "blog/:title"
Turns out all the theme code is in JS so we a package.json and YAML config file there.
I’m gunna make a few changes to the site and migrate all my blog posts over, they’re already written in markdown so shouldn’t be too bad.
Copy all the markdown files from old static site generator (Hexo) to new static site (Hugo):
$ cp -a connor11528-blog/source/_posts/. connorleech.info/content/posts/
Now all my blog posts are in the right place and the URL is configured so that it works. One thing that I do have to watch out for though is my old blog posts files had a config object at the top that did not have
--- as the first line. Otherwise the blog post config will be almost exactly the same! Both static site generators should read the markdown just fine.
What’s left for me in this transition is to add
--- to the first line of all my blog post markdown files without deleting anything. I couldn’t figure out how to do it using
sed so I went through and added it to all the blog posts, should be good to go.
To deploy to Netlify I pushed to a GitHub repo and linked the master branch to my Netlify site. Netlify has some docs about Hugo deployments here. One gotcha that I encountered was an error when I triggered a deploy of Hugo not being defined:
5:28:57 PM: Executing user command: hugo 5:28:57 PM: Started building sites ... 5:28:57 PM: ERROR: 2019/12/29 01:28:57 template.go:477: template: /opt/build/repo/themes/ananke/layouts/_default/baseof.html:9: function "hugo" not defined 5:28:57 PM: ERROR: 2019/12/29 01:28:57 template.go:477: template: theme/partials/site-footer.html:4: function "now" not defined 5:28:57 PM: ERROR: 2019/12/29 01:28:57 template.go:477: template: theme/partials/site-navigation.html:19: function "partialCached" not defined 5:28:57 PM: Error: Error building site: unsupported file extension .toml
My configuration had the proper build command and publish directory:
The issue was that I needed to specify my Hugo version (HUGO_VERSION) as 0.62.0. Ideally this would be the default butwhatcanyado.
My site really isn’t anything fancy. It’s literally just a bunch of blog posts on a website with my name on it. Going forward I’d totally be open to learning more about custom themes and maybe even building my own. I’d also like to explore some of Netlify’s more advanced features like serverless functions, CMS and identity. For now though I’m happy to have a site live with easy deployments that I can build on top of. It’s also fun learning about new tools and technologies!