I’ve been running my personal website for about 3 years now and am very happy running a static site generator. I’ve picked Jekyll in the past because it was the most viable option at the time. Today, static site generators are more popular and I’ve decided to switch to Hexo.

In this post I will summarize the steps taken to convert the Jekyll codebase to Hexo.

Why I moved from Jekyll to Hexo

I don’t want to take too much of your time with this. Basically I’m way more comfortable with Javascript than I am with Ruby. Hexo is written in Javascript, so it feels more natural to me than Jekyll (which is written in Ruby).

From all the Javascript based options available, Hexo has everything I need included in the default package so I don’t need to modify too much, depend on plugins or use very powerful frameworks for a simple blog (yes Gatsby, that’s you).

Step 1: Create Hexo project from scratch

Prerequisites
For this post I’m assuming you have Node.js and npm installed already.

Now open a shell where you want to create your new Hexo project and follow along:

# Install the Hexo CLI
npm install -g hexo-cli
# Initate a new Hexo project in the ./hexo-site folder
hexo init hexo-site

After this, open the hexo-site folder in your favourite editor.

Step 2: Basic configuration

I found I had to modify these settings to match the settings of my Jekyll setup. The post_asset_folder setting helps to organise post images etc., which I found was missing in Jekyll.

Edit _config.yml and have a look at your general settings, paying attention to the specific settings below to closely mimic Jekyll:

permalink: :category/:title/
new_post_name: :year/:year-:month-:day-:title.md
pretty_urls:
  trailing_index: false # Set to false to remove trailing 'index.html' from permalinks
  trailing_html: false # Set to false to remove trailing '.html' from permalinks
post_asset_folder: true # optional
pagination_dir: .
category_dir: /

Step 3: Move posts to Hexo

This step is straighforward, just move the /_posts folder in Jekyll to /source/_posts in the Hexo folder.

If you have enabled the optional post_asset_folder setting in the config file, Hexo expects each post file to be accompanied by a folder that matches the filename (e.g. post /_posts/my-first-post.md has matching folder /_posts/my-first-post/.

To create the matching folders automatically, have a look at my separate post here: Automatically create Hexo asset folders for existing posts

Step 4: Posts conversion

You can try to run the command hexo server now. If you’re migrating from a ver simple Jekyll setup, it might actually work. In my case however, I had to convert a number of posts to be compatible with Hexo. This was mostly because I’ve used Liquid template tags like {% highlight %} or {% include %} in my posts. Liquid does not work in Hexo by default.

For the conversion, almost all problems could easily be resolved by using the correct Hexo Helper for the problem. Once I discovered this, the conversion went pretty smooth and I only had to write 1 custom Hexo Helper to get my posts.

Step 5: Template conversion

At this point, your posts should work but the output from hexo server probably doesn’t look like your previous blog at all. That’s because the Jekyll templates have to be migrated and converted.

Create a new folder in the /themes folder with a name of your choice. I would recommend to have a look at the default template that’s in the folder and try to match the default template structure at first. The default Hexo folder structure allows you to neatly organise your files and it’s one of the things I like about Hexo.

Hexo uses EJS templates for its templates by default. This isn’t what Jekyll uses, so they need to be converted.

I can’t really help you here, but studying the default template in the /themes folder and basic EJS knowledge was enough for me to get this done.

By default Hexo comes with a few settings I didn’t really like. I’ve created separate posts for this, I’ve listed them below at the end of this post.

Step 6: Moving styles to Hexo

For this I’m assuming you’re using Sass SCSS for your styles.

Move your styles to /themes/[your-theme]/source/_scss/

Next, make sure you have the Hexo SCSS renderer installed. If not, run:

npm install --save hexo-renderer-scss

This should generate the styles for you in the public/css folder when rendering with the hexo generate command.

You can reference the CSS files in your templates like this using the CSS Helper function:

<%- css('css/style') %>

Step 7: Moving scripts to Hexo

This step is pretty straightforward. Move your JavaScript files to /themes/[your-theme]/source/js and they will be rendered to /public/js. You can use the JS Helper function to reference the JavaScripts in your templates:

<%- js('js/script.js') %>

Step 8: Moving assets to Hexo

Any folder created in the /source directory that is not prefixed with an underscore (_) character, gets copied to the /public folder when rendering. So your favicon.ico file can be put directly inside the /source folder. You can also create subfolders to organise your assets a bit more (recommended).

As for post assets (e.g. images) that get referenced in the posts, you can either create a separate folder or use the post_assets_folder option mentioned in Step 2. If you’ve configure the post assets folder, put all post assets in their corresponding folders in the /source/_posts folder.

Further reading

You should now have a fully functional Hexo blog. To keep this post simple and readable, I haven’t covered the more advanced topics yet.

I will write additional posts on more advanced topics in the near future and will directly link them here for your convenience.

Template Customization