Migrating from Hugo to Wordpress

Thu, Jan 20, 2022 5-minute read

Migrating from Wordpress to Hugo

Important caveat: I am not a Hugo expert. I almost said not yet. But I doubt I ever will be. I am literally winging this. The main Hugo site is really good and far better than this site.

Migrating from Wordpress to Hugo was actually a reasonably straight-forward process. There are plenty of articles out there covering it and I was following this one and this one- which also does a nice job of why you might want to move to Hugo (or a static site) in the first place.

Installing Hugo

I’m on macOS so installation was super easy using Homebrew.

brew update
brew install hugo

That’s about it really for installation. Once you’ve got a local install, best thing to do next is to have a quick play using the Getting Started which includes creating a site, installing templates, building and previewing content and so on.

Migrating Wordpress

This is where things got a little trickier. I tried various Wordpress-to-Hugo plugins in Wordpress but none of them worked adequately. The output was all sort of ok but when [importing](https://gohugo.io/commands/hugo_import/ in to a Hugo site the structure and content itself was knackered. I’m not sure of the main cause - but I tried it on two different WP installations - one, the 20 year-old shitpot that is this website; but also a small and relatively vanilla and very simple Wordpress blog and that also didn’t work well.

The good news is that

  1. In the Wordpress plugin-marketplace-thing there is an authorised Wordpress-to-Jekyll exporter and
  2. The Hugo CLI has a built-in jekyll import.

This worked very well, including doing a pretty decent job of converting some of the WP content into markdown - not perfect, but got it a lot of the way there.


By far the most tedious part of this whole process was tidying up the content of the articles. I started with over 500 posts but a lot of this was historic junk so the first job was to trim it down to the set of articles I wanted to keep, which was around 150-200.

The remainder of the effort will depend on the condition of your Wordpress environment and how well you tagged and categorised things there.

Embedded HTML and special chars

Since my blog does have code excerpts, the first thing I had to was tell Hugo to allow HTML in the posts, which for some reason Hugo refers to as ‘unsafe’ mode. Without this, all HTML in your pages is rendered (Which means it will likely disappear.)

This is done in your config file.

unsafe = true

(if you’re using toml)

Related to this though is what Wordpress would do with special chars - it would store them in encoded format so an apostropher (’) would be stored as ’. Unsafe mode will decode these in the main text but doesn’t apply to page titles. I gathered up a list of the characters affected, and then used Find and Replace in Files in Sublime Text.

Content clean

I tidied up a lot of links and image references using a similar technique. I wanted, as far as possible, for references to Wordpress to be taken out - and this includes images and links. Wordpress does a horrible job of (a) storing absolute links to resources and (b) completely over-barfing everywhere with the HTML. The amount of spew produced for just displaying images was likely one key part as to why the old site performed so badly due to the sheer weight of the page (not to mention creating 10 different versions of an image at the various resolutions which can now be handled with CSS).

I wasn’t going to tidy every single page manually, so for there will still be some remnants of the WP install. But really a case of finding patterns and then replacing. This took a while. And wasn’t much fun. I figured out which images needed keeping and manually moved these from my export, copied them in to the Static folder and set the relative link accordingly in the output. There are better (more Hugo) ways of doing this but for just getting it working, this was fine.

Comments system

I wanted a comments system but did not want to go with Disqus for widely published reasons. There are a bunch of options out there… Commento… Isso… and various others… but I opted to go with HashOver due to various reasons - it’s mature and been around for a while - andn also the server options I have for hosting.

I found two useful guides - here and here.

These were enough to get it installed. It was installed in a sub-domain and the only additional point was to then install the system in a folder in that sub-domain, rather than the root of it. There seems to be some reference issues that meant CSS / scripts etc. didn’t load, which was resolved when it went in a sub-folder of the sub-domain. Odd.

I’m not yet completely sold on this system. It does work - and is nice enough - but have encountered a few weird bugs, such as duplicate comments and logging out not doing anything. I also haven’t yet migrated comments from Wordpress and it’s frustrating to not be able to run it locally.


Deploying is a different matter and there is a later post on how to do this. The other new habit to get in to is using source control to move stuff around. I may shift this in to something like Dropbox.

That was all, though.

Posts in this Series