Migrating to Hugo
Tags: blog, staticsite
Published: 2020-06-23 07:32:35

(Cover image credit: Kenneth Canning/Getty Images)

So I finally decided to do it, after thinking about it at least a dozen times: I switched from using Wordpress to Hugo for my blog. I watched most of my online friends do it too the last couple of years. And all but a few ended up with a static generated site (with Jekyll, GitHub Pages or Hugo) but were pretty excited about the results. 

I also thought of all the great things a static generated site would have to offer, things like writing articles in MarkDown using my favorite editor (Visual Studio Code) and total control over the generated HTML output. The reason I hesitated was, that I thought it would be a lot of work not to mention all the great features I would be missing out on (the Wordpress plugins).

It turned out to be pretty easy to do and can now also join my friends in excitement. Static sites rock.
The only thing left for me to do is, making sure everything works as expected. And that is why sharing my migration notes on my new Hugo powered platform seems like the perfect thing to do right now. 

### TL;DR
Wanted to move from Wordpress to a static website. Picked Hugo and Azure Static Web Apps. Migrating content turned out easier than I thought, DNS a bit tougher. I can now use Visual Studio Code and Markdown for writing articles. Ended up with a blazingly fast website behind Cloudflare.

1. Pick a static website framework
2. Select a hosting provider
3. Migrate content (text and media)
4. Fix the links (permalinks and custom 404)
5. Adjust DNS
6. Enable Search
7. Configure a new content workflow
8. Trigger social media
9. Configure analytics


### Static website framework 
The reason for me to look beyond Wordpress for my blogging site was not because I wanted to join my friends screaming with excitement. Well not the only reason. My basic needs were:

- Improved workflow: I never liked writing my articles in the browser and usually prepared them in Microsoft Word or Notepad++. To be able to work with any editor and Markdown as the underlying language seemed real nice. Content as Code!
- Markdown: To be able to use it as a markup language with its plain-text formatting syntax. The reason is simply because of exit scenarios. As we will see later on, getting your own content out of a CMS can be quite challenging. Because of the minimum formatting, Markdown enables you to migrate your blog content with ease.
- Speed: I have a simple blogsite, nothing special. And somedays WP was just super slow and it took seconds to load my site. 
- Theming: I am no CSS warrior and prefer to build on the great work of those who are.

Picking a framework can be hard, so I just evaluated a couple that seemed to fit the basic needs. My shortlist was:

- [Hugo](https://gohugo.io/)
- [Gatsby](https://www.gatsbyjs.org)
- [Jekyll](https://jekyllrb.com/)
- [VuePress](https://vuepress.vuejs.org) 

There are many articles on the web comparing these frameworks so if you want to know more about the differences, I suggest checking those out. My evaluation was simple: can I get a basic site up and running in under 10 minutes. As it turns out, all of them qualify :)

In short: I went with Hugo, but mainly because of the available [themes](https://themes.gohugo.io/).

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/fxcd7lmuod7djxsfi6fa.png)

My next step was, getting to know the new platform. There is probably no better way than writing my first post (this one) to see if I can find my way around. But because I was also hosting my blog on wordpress.com, I also needed to look for a new provider.

### Hosting

Not surprisingly hosting a static website is the most basic thing to do and every provider has support for HTML files and images. There are so many options out there, just pick one. The only thing to watch out for is how you can "upload" your content. If you only have legacy FTP, you might be missing out on all the great features other hosting options have.

I picked Azure Static Web Apps, a new and shiny (also very much in preview) service from Microsoft.

A note on Azure Static Web Apps:
There is currently no support yet for "naked" (APEX) domains. This means that https://www.yuriburger.net works out of the box, but https://yuriburger.net does not. A workaround is available for the time being, but this involves Cloudflare. See later on this article for the details on that.


### Content (the most important part of course)

I had not that many blogposts to migrate, maybe 80 or so. And I choose to leave a big part of that content behind, because I considered them outdated and/or not relevant anymore. Still what was left, needed some form of automated migration. Luckily the Hugo website has some links on tools that can help you with this. As it turns out, these tools focus on exporting WP content to Markdown and can be used with other blog platforms as well.

I choose to export the WP content (articles and media) and converted the text using the exitwp-for-hugo Python script.

Next, I migrated (actually just copied) the converted files to the Hugo file structure. This was the part that I "feared" the most and it took only minutes.

More info on the WP export scripts: https://gohugo.io/tools/migrations/#wordpress 

### Perma links (fix all the old links)
All that "old" links pointing to the old site? Usually not a problem, because most static site frameworks have a way to generate the same permalinks. In my case, I just had to make sure my articles have the correct (original) publish date.

In Hugo, this is accomplished by adjusting the config.toml file:

```
[permalinks]
  blog = "/:year/:month/:day/:title/"
```

Boom, easy fix. Now I needed to write a custom 404 (Not Found) for the cases someone used an old link pointing to content that I left behind. In the case of static websites, it is not the framework (i.e. Hugo) that handles this, but the hosting platform. In my case, I needed to provide a custom 404.html and adding a "routes.json" to the generated output and make sure it was uploaded to my Azure Static Web App.

```
{
  "routes": [
  ],
  "platformErrorOverrides": [
    {
      "errorType": "NotFound",
      "serve": "/404.html"
    }
  ]
}
```
More info: https://gohugo.io/templates/404/)

### DNS (downtime about to happen)

I also hosted my DNS at Wordpress and that needed to change for various reasons. This was actually the hardest past, because it is tough to do without downtime. I wanted to move away from WP entirely so I transferred my domain to a new Registrar.

AS I mentioned in the beginning, Azure Static Web Apps do not (yet) support "naked" (or APEX or root) domains. A fix is not that hard, but requires a little bit of DNS trickery. All written up very well, so if you are like me and just want to use Azure, check this out https://burkeholland.github.io/posts/static-app-root-domain/ 

As a bonus, you will end up with a Cloudflare instance in front of your website. It speeds up your already fast website!

### Search (yes, static sites can have search)

Search was on my checklist, but I decided I could live without it. Most of my stuff can be found using categories and tags. Turns out, there are Hugo themes that support search. Even on a static web site and that is pretty neat! If you also picked Hugo, then check out this theme https://github.com/pacollins/hugo-future-imperfect-slim for an example.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5v5pss6e9h7jp2f6ygfe.png)

### New content workflow (GitHub Actions FTW!)

Content as Code. This also means you can store your content in Azure DevOps, Bitbucket or GitHub. I choose the latter and setting up your content publishing workflow is now as easy as configuring a build pipeline. 

As it turns out, Azure Static Web Apps has an even easier option. It can configure a GitHub Action directly from the Azure Portal. It recognizes the Hugo filestructure and configures the build and release automatically. Very impressive!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/eugdqj8df05l2d4f486q.png)

More info here: https://docs.microsoft.com/en-us/azure/static-web-apps/github-actions-workflow 

### Trigger social media on new posts

Turns out, the only WP plugin I used was for triggering social media on new posts. And Hugo has no built in support for this (because it is a static generated website). It requires daisy-chaining a couple of (free) tools to accomplish, but someone shared the struggle for us to copy: https://dereckcurry.com/posts/automatically-tweeting-new-hugo-posts/ 

I decided not to use this for now, as I don't mind drafting up a tweet every now and then.

### Analytics

Wordpress Analytics --> Google Analytics. Not that hard, because Google Analytics have way more detail and features so no harm in switching Google for Wordpress. The frameworks I checked all had configurable support for Google Analytics.

Thats it, at least it was for me. On the whole, it took me an evening and I think it was totally worth it. 

/Y.

More info on Azure Static Web Apps (be careful, in preview):
https://docs.microsoft.com/en-us/azure/static-web-apps/custom-domain