Seeing that shokaX-hexo is planning to migrate to Astro, I decided to migrate my own blog as well. Astro offers superior performance compared to Hexo and represents modern best practices, whereas Hexo is becoming a bit outdated.
Following the recommendations from ShokaX, I performed the migration roughly in the following order. You can refer to the official. ShokaX Astro Blog Theme
1. Setting Up the Astro Environment
Locally install bun.sh:
curl -fsSL https://bun.sh/install | bash
# or
npm install -g bunThen fork the ShokaX github repo to your own account, then git clone it.
git clone https://github.com/your-user-name/astro-blog-shokax.git
cd astro-blog-shokaxInstall requirements and launch the development environment:
bun install
bun run devNow you can visit http://localhost:4321 in your browser to preview your blog.
2. Copying Articles To New Directory
Hexo articles reside in source/_posts/, while Astro stores them in src/posts. The directory structures are mostly similar. Just copy your markdown files to the new directory (the existing subdirectory structure can be preserved). Move pictures to src/assets/images.
After doing this, you may encounter several build errors. While most solutions can be found in the official docs, some undocumented issues I occurred are recorded below:
1. Front-matter: Cover, Tags & Categories
Cover can’t be a remote URL. You can download the images and use the relative path. Or ShokaX may add this feature in the future.
And Tags and Categories must be wrapped by [] now.
2. Callouts Only Render In .mdx
If you use callouts in a plain .md file, the styling and effects will not render properly. Use .mdx extensions for these files.
3. Configuring Astro
It’s highly recommended that not to modify the default setting src/toolkit/themeConfig.defaults.ts directly. Instead, copy it to src/theme.config.ts and edit here. And change export const DEFAULT_THEME_CONFIG: ShokaXThemeConfig = { to export default defineConfig({.
While editing this configuration file, you might encounter unexpected build errors. If that happens, you can manually clear the cache and rebuild: rm -rf .astro && bun run build.
Most configurations are detailed in the official documentation, so I will only highlight the unlisted ones here:
1. Disabling Navigation Bar Link Actions
The official docs mention that href cannot be null. To prevent a parent navigation menu from triggering a redirect when clicked, configure it with href: "javascript:void(0);". Here is an example of a plain drop-down menu:
{
text: "Tools",
href: "javascript:void(0);",
icon: "i-ri-tools-line",
dropbox: {
enable: true,
items: [
{
href: "url1",
text: "Server Status",
icon: "i-ri-server-line",
},
{
href: "url2",
text: "Online Clipboard",
icon: "i-ri-clipboard-line",
},
{
href: "url3",
text: "Temporary Email",
icon: "i-ri-mail-open-line",
},
],
},
},2. Changing Favicon
To replace the default favicon, create a public folder and place your favicon.svg inside it. If your icon is not in SVG format, you can either convert it or replace the filename and update the corresponding link tag in src/layouts/Layout.astro:
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />3. Modifying the Site Establishment Time
In hyacine.plugin.ts edit siteCreatedAt:
plugins: [
SiteUpTime({
siteCreatedAt: "2025-03-03T00:00:00Z",
}),
MouseFirework({
colors: [
"rgba(255,182,185,.9)",
"rgba(250,227,217,.9)",
"rgba(187,222,214,.9)",
"rgba(138,198,209,.9)",
],
count: 30,
radius: 16,
}),
],
});4. Deploy to CloudFlare Pages
Commit your changes to git:
git add . && git commitIf you forgot to fork the official repository initially, you can create a completely empty repository on GitHub and update your remote URL as follows:
git remote set-url origin git@github.com:/your-user-name/your-repo-name.gitAnd push to github:
git push -u origin mainLog in to cloudflare dashboard, select Pages, and Connect to Git. Select github and your repo, Framework preset select Astro, Build command : bun install && bun run build. This selection is detailed in official docs.
5. Managing Future Upgrades
Add official repo to upstream:
git remote add upstream https://github.com/theme-shoka-x/astro-blog-shokax.gitWhen there is a new official version, run this:
git fetch upstream
git checkout main
git merge upstream/mainResolve any potential merge conflicts, then commit and push the updates:
git add . && git commit && git push -u origin main6. Extensions
1. RSS
Add this extension:
bun add @astrojs/rssCreate a new file src/pages/rss.xml.ts:
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import type { APIContext } from 'astro';
export async function GET(context: APIContext) {
const posts = await getCollection('posts', ({ data }) => {
return data.draft !== true;
});
const sortedPosts = posts.sort((a, b) => b.data.date.getTime() - a.data.date.getTime());
return rss({
title: "Onirexus' Blog",
description: 'Out of Office',
site: context.site ?? 'https://blog.onirexus.com',
items: sortedPosts.map((post) => ({
title: post.data.title,
pubDate: post.data.date,
description: post.data.description || '',
link: `/posts/${post.id}/`,
})),
customData: `<language>en</language>`,
});
}The subscription URL is https://yourdomain.com/rss.xml.