Migrating Wordpress to Hexo and what to be careful about.

Since 2008 this blog was running on Wordpress. This makes Wordpress my loyal servant for almost 12 years. However, as everything else, Wordpress started showing it’s age. The performance of the PHP powered system started lagging behind some other alternatives. While being a great general purpose solution, that is being used for anything from hobby websites to ecommerce shops, I probably didn’t use 10% of the features that Wordpress provided. Mainly because of these two reasons, I decided to migrate to something more simple and easy(as well as cheaper) to manage.

After some searching on the internet, I saw that a system called Hexo is a hot thing right now, so I’ve decided to go with it.

Migrating Wordpress posts

Important to do before you start migration:

  • Change the setting new_post_name in _config.yml from :title to :year-:month-:day-:title.md
    This change will make it much easier to locate/sort posts for editing later on.


  1. Export Wordpress data from the dashboard through “Tools” -> “Export” -> “All content”
  2. For automatic migration execute command hexo migrate wordpress /path/to/<your_wordpress_export_file>.xml --paragraph-fix --skipduplicate --alias --import-image

Installing the theme

git clone https://github.com/ppoffice/hexo-theme-minos.git themes/minos

Disadvantages of automatic migration

  • Does not migrate tables at all. Instead we have to use a tool like:
  • Causes Hexo to crash with some migrated files - in my case _drafts
  • Sometimes causes duplicate posts
  • I have a custom YouTube embed implementation that will not be converted
    <div class="youtube-player" data-id="qWiDI0FC0Q8">
  • Doesn’t convert lists, paragraphs, etc inside a table correctly
  • Didn’t correct bold paragraphs correctly
  • Generates .md files for non-existing posts with Wordpress metadata
  • Alias plugin didn’t exactly work, had to do the following
    Replace \/blog\/archives/([0-9]*) with /archives/$1/index.html excluding README.md
  • Change tag_dir from tags to tag in _config.yml to reflect Wordpress settings
  • Subpages didn’t get correct alias and were not placed in the correct folders
    projects/cs-sms-admin/index.md was placed in cs-sms-admin/index.md
  • Categories pages were a challenge to setup
    • Wordpress uses /archives/category/<name> while Hexo uses <category_dir>/<name>
    • We could change category_dir to category instead of categories but this still leaves us without /archives/ in the beginning
    • I tried making subfolders(pages) with redirects, but the pages only supports one of redirect or alias - alias takes priority
    • Lastly soulution was to define alias in _config.yml, but this is major inconvenience, because you have to do it and restart the server everytime you want to add a category
    • At the end I’ve decided to use statically generated pages
  • It’s difficult to change between themes - i’ve setup my blog with Minos, but when i tried changing to the default template - it was horrible
  • Ugly templates or lack of such
  • My template doesn’t show post tags and categories on list pages like the home page, categories pages, etc.
  • Depending on the theme, static files generation was missing CSS and Scripts - had to setup Stylus renderer manually, even though it was included
    After some research I found out that there was no problem with Stylus - the problem was with Nginx not sendings CSS files.

Note: some of these changes were made to preserve the original Wordpress settings for SEO reasons and compatibility, if you don’t need them, you can just use Hexo as it is.

Additional steps

  • If you use a reporsitory, make a new repository or branch for the generated files - Github actions can generate the blog files for you.
  • Follow the guideline on the Hexo website and add a github workflow to generate the site in a branch

Problems I faced

  • The workflow was failing because an alias was set wrongly
  • Fixed the alias and pointed the server to clone that branch
  • Deleted my images in the process
  • Update: after checking in the evening - the images are there. I’m saved - I was just planning how to restore them from the internet and backups.
Why is PayPal bad and what alternative to use instead? How to setup Logstash internal logging in Docker