Migrating my blog from WordPress to Hashnode

Migrating my blog from WordPress to Hashnode

·

7 min read

A step-by-step guide for migrating a blog from WordPress to Hashnode.

Why did I switch from WordPress to Hashnode?

Currently, my portfolio website and blog are on WordPress. It's been really great for search engine optimization, and the experience with WP Engine has been almost flawless, but it's been a long time since I built it so everything I use to run it locally is broken: Vagrant, Scotchbox (LAMP stack), WP Distillery (Wordpress-flavoured LAMP), etc. It's no longer as quick as it used to be to make small changes.

I have been evaluating different blogging platforms. I considered Medium, but I am not a fan of the experience of landing on a Medium link and hitting a paywall, so I didn't want users to experience that if they find one of my posts. It also didn't have any ads injected, so that's great.

I also thought about using a headless CMS and a static site generator like Nuxt as I've had a great experience with it, but that would've taken a lot of dev time to build. I think that's something I would do for the rest of my site once I have more time.

Hashnode has a variety of features that I appreciate:

  • Markdown editor
  • Canonical link support so I can link to my original post if I wanted to
  • Automated backups to a Github repository
  • Custom domain linking
  • Nice code syntax highlighting, with the bonus of embedding external services for code snippets

What's great is that these are all free, too. There's also a helpful community on Discord to get some help if needed.

Walkthrough for migrating from WordPress to Hashnode

Download post content

To begin the migration, you'll need to download your existing posts. By default these are in XML format. Since I don't really like working with XML, I used the plugin WP Import Export Lite to export my posts as JSON.

wp-import-export-lite.png

The resulting output was an array of objects that had the following shape.

{
  "ID": "463",
  "Title": "iTerm colour schemes",
  "Content": "Introducing 2 iTerm colour schemes [...]",
  "Excerpt": "iTerm colour schemes based off of my Visual Studio Code theme",
  "Date": "June 22, 2020",
  "Post Type": "post",
  "Permalink": "https:\/\/tinaciousdesign.com\/blog\/iterm-colour-schemes\/"
}

Download images

Next, you'll need to download all your images. There's more than one way you can approach it:

  1. Download all of the images uploaded to your WordPress install
  2. Programmatically process a JSON or XML export of the Media Library, which has links to the media

The first option is by far the easiest, so I went with that.

Images are stored in the ./wp-content/uploads directory by year and month.

wp-content/
└── uploads
    ├── 2019
       ├── 01
       ├── 02
       └── 03
    └── 2020
        ├── 01
        ├── 02
        └── 03

Your posts reference images like this:

https://example.com/wp-content/uploads/2020/08/filename.png

You can use an SFTP tool like Cyberduck or FileZilla to download this folder.

Upload images elsewhere

Update: This section is out of date. The service Fast no longer offers a free plan and Hashnode has its own CDN so I have been manually updating them in an effort to save on server costs.

That "elsewhere" I chose is Fast.io because it had a generous free plan that leverages a variety of storage options like Dropbox, Google Drive, OneDrive, etc. I can take advantage of one of those amazing storage services and link it to Fast.io. I chose Dropbox. After manually deleting some images that weren't used in the blog posts, I uploaded the entire contents of the downloaded ./wp-content/uploads directory to Dropbox.

Programmatically publish posts to Hashnode using their API

Hashnode has a GraphQL API. It's somewhat limited in functionality but has most of the basic features. There's a helpful blog post on how to use it.

Back-dating posts is not supported in the API so I needed to do this manually for each of my posts, which was tedious.

I've created a repository of the scripts I used to facilitate cleaning up and bulk uploading posts.

Conclusion

Overall, I was happy with my migration to Hashnode. It didn't take very long. Hashnode has a lot of features I look forward to using and I was happy to invest the time in migrating.

Setting up my custom domain was a bit painful compared to other services I've set up domains with, e.g. Heroku, Netlify, Github Pages, Amazon S3. I use Cloudflare, and eventually what worked was contacting support on Discord, disabling Cloudflare's default proxying behaviour, and waiting until the SSL certificate was re-generated. Within a day it was working, so the trouble was only a minor setback.

The authoring experience is nice, typographically. There's also support for a lot of different types of embeds. Showing code is pretty without any effort on my part, and their embeds support the services I use most (Codepen, Codesandbox).

Overall, migrating to Hashnode is a relatively low investment, low risk migration.

If you like the sound of this and want to migrate your WordPress blog to Hashnode, you can use some handy scripts I created.