Home About Me

Moving My Blog from Typecho to Hexo, One Piece at a Time

Preface

After trying different setups over and over, I ended up back where I probably belonged from the start: a static blog.

It is more secure, has very little performance overhead, and with GitHub handling hosting, it practically eliminates server costs. At that point, keeping the site alive mostly comes down to renewing the domain every year. Images still need a proper long-term solution, but that is a problem that can be worked out.

There is something oddly bleak about this kind of migration process—like packing up the whole household again and again just to stay somewhere stable.

Breaking the migration down

A blog can basically be split into four parts:

  • Posts
  • Comments
  • Images used inside posts
  • Site assets and decorative resources

The most important part is obviously the posts themselves, so that was the first thing to solve.

I found a plugin on Gitee that looked promising, so I decided to install it and see whether it could export the content cleanly.

Exporting posts with the Tp2MD plugin

First, I logged into the server remotely, uploaded the ZIP file I had downloaded locally, and extracted it.

Then I moved into the plugin directory: /usr/share/nginx/html/usr/plugins

Unzip the archive: unzip Typecho-Plugin-Tp2MD-master.zip

Rename it to the directory name required by the plugin instructions: mv Typecho-Plugin-Tp2MD-master Tp2MD

After that, I signed into the site admin panel, enabled the plugin, opened its settings page, saved the configuration, and accessed it according to the tutorial.

At that point, it threw this error: 不能写入文件,请检查 cache 文件夹权限!

The fix was to change permissions for the cache directory inside the plugin folder: sudo chmod -R 777 cachea

Be careful here: it has to be the cache folder under this plugin directory.

Once the export reported success, I went into that directory, compressed the exported files, downloaded them, and checked the result.

Some of the exported folders were a bit messy, probably because a few of my posts belonged to multiple categories. That did not matter much. The structure could be cleaned up later—the important thing was that the post content had been extracted successfully.

So that took care of the articles.

Comments

Comments were easily the most frustrating part of the whole migration.

I spent two days trying just about every option I could think of: Disqus, Valine, Waline, Utterances, Twikoo, and Atalk. In the end, I settled on Giscus.

I am fully aware that this means readers without a GitHub account cannot leave comments, but the other systems all ran into one strange issue after another that I could not solve properly: Cloudflare blocking requests, CORS problems, servers being inaccessible, and random 404 or 403 errors.

I really did try.

Post images

Moving image files

I went into: /usr/uploads/

Then I compressed and downloaded the image files.

After that, I reorganized the image structure for Hexo by copying all images into: source/images/

The image paths in the posts then had to be replaced manually. One detail to keep in mind is that static asset resolution uses source as the default root directory, so absolute paths based on source work directly.

Deploying with Vercel for faster access

  1. Register a Vercel account
  2. Create a project and connect the repository
  3. Configure domain DNS

As of 2025.3.3, the blog migration was fully finished.

Roughly speaking, it took six days in total, mostly because I did not have much uninterrupted time to work on it. The longest and most exhausting part was still the trial-and-error process around the comment system.