Switching from WordPress to Hugo and JAMstacks

More election distraction… Well, I’ve been, for over 15 years WordPress and it’s probably time to leave the family.

A Brief history of tongfamily.com

Originally, tongfamily.com started in 1996 with FrontPage Extensions. Then in 2003, I finally had some time and switched to Ben and Mina Tratt and their Movable Type in 2003 blogging platform (see Wayback Machine) and that led to b2 and then onto WordPress which appeared in 2008 (see Wayback machine) when I finally switched there as a reasonably early user.

In the past 12 years, I’ve used it and it has become the dominant platform but has always had some limitations. The biggest one being configuring and maintaining it. You basically either have a pure hosting platform. I started with TQHosting and then moved to Bluehost and finally to Digital Ocean, but in the end, you have to maintain plugins, make sure the server doesn’t run out of memory, and so forth. I’ve tried things like Ghost but those didn’t get far mainly because they didn’t have an easy blogging platform.

Today what makes WordPress great are the editing tools and the zillions of themes that are everywhere, but maintaining a server isn’t easy. You have to make sure that Mysql is up and there is no way to manage the revisions and figure out what is going on with the configuration easily

Now Alex told me about Hugo which is completely different, it like Ghost (also from a WordPress alumni) is a static site generator. The best thing about it though is that you can check it into GitHub and maintain it that way. Then you can use tools like Netlify to just automatically note check-ins and publish. It’s a dream for a developer-oriented (vs writer oriented view of the world).

This has opened a whole new world where the different pieces of monolithic WordPress have been split, but the easy way to see it is to look at the four big parts of a website:

  1. Theme. That is actually the equivalent of the “app” in the software world. So much of this world is now having a big library so you are just modifying code. The WordPress themes are one of the huge advantages of that platform.
  2. Site Generator. This basically means how you take content and create the web pages taking into account dynamic content etc. WordPress has a huge amount of PHP code that makes it super easy to take data and then dynamically assemble it to create the page. That is how you get widgets and other cool things.
  3. Content Management System. This is how you author things and keep them up to date. The editing tools and the ability to set drafts and things is really important and WordPress integrates all that.
  4. Repository. Where you store all that data and make sure it is up to date. In the old days, they would call it the database. In WordPress land, the default is MySQL and you can create anything you want that way.

But this monolithic system has a bunch of issues and the modern way of doing this is called JAMStack which means (a front end made up of Java, Web API calls and Markup. Instead of the logic being on the server side, the webpage just make direct calls into the Internet for services.

There are some huge benefits to going this way:

  1. Open. There is no lock in as these are a collection of tools that you can replace and change.
  2. Performance. WordPress does have a system for prerendering pages and caching them, but JAMstack takes this to the limit. The entire site is generated as static pages. That means that you don’t need a network of WordPress instances, you can just spray pages everywhere.
  3. Security. Because these are static pages and you are not embedding logic there, the attack surface is limited to the APIs (so you can’t inject code into a client-side page and take things over). And the fact the pages can be read-only reduces the attack surface.
  4. Development. This is much faster to write for because when writing the front-end, you don’t have to know anything about how the backend works. You just hook into an API and you can use standard tools that all developers love (like GitHub) rather than a proprietary web tool.
  5. Scale. Static page hosting is much simpler and that means easier to scale to millions of people. And it is going to cheaper too because you just stick the pages into a CDN and you are done.

Well, the big change in the world in the last 10 years has been moving away from these monolithic systems to having separate choices for a long time and it has been painful to put it all together. So given all this, there are some great choices now across these fronts, the one we are exploring is:

  1. Themes. Hugo has a bunch of momentum and good enough themse
  2. Site Generator. The aforementioned Hugo. There is also Gatsby and many others, Jekyll and Next.js
  3. CMS. The big choices here are Forestry and NetlifyCMS, DatoCMS
  4. Repository. Having everything in a git repo is a huge benefit. And of course, if you are doing really custom stuff, then you can always edit the git pages directly.

The main disadvantage of this has been that putting all this together is a real pain, but with tools like Stackbit we are finally seeing the power of open-source married with the convenience of a single vendor. This is a cool tool that lets you select each one of the four things, mix and match and then publish a site. So you get the ease of WordPress and the power of JAMstack. But first, let’s do a simple installation just to learn how to make Hugo work with Netlify.

Now onto Hugo in detail

Hugo is almost the completely opposite of WordPress. Rather than a rich user interface, it is completely GitHub driven. so it acknowledges the fact that most blogs are more like single page web apps and that the content creation is less important than the management of all of it the speed.

Because it renders to static web pages it is very fast and it can be hosted just about anywhere. From Amazon S3 to Github pages to Netlify. Netlify is a free tool that lets you host your site (and do many more things later on, but that’s another story). The main thing is that there is not a server-side to maintain, so you don’t have to be reliant on managing your own server nor on a serving hosting company getting it right.

Getting started with Hugo

The startup is incredibly simple as their guide shows:

  1. First brew install hugo gh to get the command line tools on your Mac (or Linux or Windows Subsystem for Linux).
  2. Then you want to create a repo for this for instance if your organization is richtong and you want the repo to be called web then it is cd ~/ws/git or wherever you put your stuff and then gh repo create ----private richtong/web assuming you are logged in
  3. Now you can initialize this with the base Hugo stuff with Hugo --force new site web to create it inside the web subdirectory. You need the force flag because the web directory already exists and is under GitHub control.

Adding a theme subrepo

Now you want to load a theme in. The trick here is that themes are also just git repos, so what you want to do is to find a theme you like, fork it so you can control it and then make it a submodule in the web:

  1. Find a them that you like at the massive directory at themes.gohugo.io or there are plenty of curated lists like the paid themefisher and some nice free ones at hugo themes free.
  2. Now create a collection of different themes in the web/themes directory so you can have as many as you want there and you can set the web/config.toml file to the appropriate one but a generic product page like Hugo Product Launch is not a bad place to start.
  3. So to get it, you should first fork it to your repo so that you can control updates with gh repo fork janraasch/hugo-product-launch and do not have it create a submodule with it with pushd themes; git submodule add git@github.com:richtong/hugo-product-launch and you should be nearly set by adjusting the theme line in config.toml to theme = hugo-product-launch
  4. Now you can create a sample page or steal the content from the exampleSite in the hugo-product-launch with a cd web && cp -r themes/hugo-product-launch/exampleSite/* . or just create a simple post with hugo new posts/sample-page.md and make sure to set draft to false in web/content/posts/sample-page.md
  5. Now you can run and see what it looks like with hugo server -D where D means show all drafts and you should be able to browse to http://localhost:1313 and see the site!
  6. And to build the pages locally, it is hugo -D and it appears in .public.
  7. The nice thing about using a submodule as an aside si that the singe command git submodule update --rebase --remote will update your theme for you.

Hugo under Docker

Note that you can also run Hugo under docker as well so you are really isolated from you host environment. It’s a little tricky to get running, but basically, you thanks to Jojomi you can do a docker run of his container and generate static pages. This seems to work pretty decently although passing commands to it like hugo new doesn’t seem to work. This will need some more hacking to get right.

I’m not sure it is that important, but in general, I think it’s good hygiene to move all installations away from native and onto docker.

Netlify with Hugo

You can host all of this on Netlify for free and it updates on every git push. So that’s a huge benefit. The way to do this is pretty easy:

The basic steps are pretty great and the net is that compared with WordPress, you do not need to have a hoster that you pay for if you have a basic site! And since they support DNS, you don’t even need someone to do that.

  1. Create a new netlify account, it is super easy if you use an existing Github credential at app.netlify.com
  2. You can also set this in the repo ahead of time in netlify.toml which is a great idea, then all the build instructions are under Git control and you don’t have to fill things out as noted below. The two key sections are in the [build] section where you have to add publish = "public" and command = "hugo --gc --minify"
  3. Then authorized the Netlify app to run and look at your repos on Github.
  4. Now go to New site from git.
  5. It’s pretty straightforward except for two magic sections, the build command to run Hugo and the location of the output directory. These are hugo and output respectively.
  6. Netlify also provides a free DNS which is pretty easy, so just point your custom domain to it.
  7. The main tricky part here is making sure that you can get Hugo to build. That depends on whether you have copied in the correct config.toml from a sample site. If not, then you need to make sure the build instructions are correct
  8. They also provide Let’s Encrypt SSL certificates so make sure to enable that.

One Gotcha: Private submodules

The only gotcha I discovered if you have private submodules in your Hugo installation. I use this because there is lib submodule I use for managing docker. Turns out that you need to have a specific private key for each submodule that is there which is pretty inconvenient or if you want to use ssh vs https encryption.. It is probably easiest if you just make any libraries you need public so you don’t have to deal with it.

If you really want that library to be public, you will need a deploy key which is a special SSH key just for that submodule. To create one, go to Site Settings > Build & Deploy > Continuous deployment > Deploy key and generate the key that you need.

Then you go to GitHub.com/_your_org_/_your_repo and settings/keys and add that public key so Netlify can access it. You need to do this for all submodules that work like this.

Taking the quick path to JAM with Stackbit or another CMS

Because Hugo splits out the editing from the management, you can use a third-party tool like Forestry to create new content for non-technical people. There seems to be a whole host of ways to do that. But that’s for another post. The main thing is the move here to this system

Porting WordPress to Hugo

There are many ways to do this, but the easiest way seems to be a WordPress plugin that exports the entire site to a Hugo set of posts. Wow that is pretty cool.

I’m Rich & Co.

Welcome to Tongfamily, our cozy corner of the internet dedicated to all things technology and interesting. Here, we invite you to join us on a journey of tips, tricks, and traps. Let’s get geeky!

Let’s connect