Migrating My Blog to MDX and Shiki
I recently migrated my blog from markdown to MDX with Shiki syntax highlighting. The old setup used vite-plugin-markdown and react-syntax-highlighter, but I wanted VS Code-quality highlighting and the ability to use JSX components in blog posts.
Configure Vite for MDX:
export default defineConfig(async () => {
const mdx = await import("@mdx-js/rollup");
return {
plugins: [
react(),
mdx.default({
providerImportSource: "@mdx-js/react",
remarkPlugins: [
(await import("remark-frontmatter")).default,
(await import("remark-mdx-frontmatter")).default,
],
}),
],
};
});
Create a Shiki component for code highlighting:
export const CodeBlock = (props) => {
const isLightTheme = useAtomValue(isLightThemeAtom);
const { children, className } = props;
const language = className?.replace("language-", "") || "text";
return (
<ShikiHighlighter
language={language}
theme={{
light: "github-light",
dark: "github-dark",
}}
defaultColor={isLightTheme ? "light" : "dark"}
>
{children.trim()}
</ShikiHighlighter>
);
};
Convert files by renaming .md to .mdx. Frontmatter stays exactly the same. Update the blog component to use MDX imports instead of the markdown plugin.
The result is VS Code-quality syntax highlighting, cleaner architecture, and the ability to use React components directly in blog posts.