Astro Markdown进阶:7个实用技巧让你的博客专业10倍

你刚用 Astro 搭好博客,开始写第一篇技术文章。想要高亮代码的某一行?不行。想加个可折叠的警告框提醒读者注意事项?做不到。想在算法讲解里加个数学公式?完全没思路。
我也遇到过这种尴尬。用纯 Markdown 写了几篇文章后发现,能表达的东西太有限了。看别人的技术博客,代码块可以标注重点、可以展示代码改动前后的对比,文章里还能嵌入交互式的组件,自己却只能干巴巴地贴代码。
好在 Astro 提供了 MDX 这个”增强版 Markdown”。说白了,MDX 让你在写文章的时候可以用组件、可以写 JSX,能做的事情一下子多了好几倍。
这篇文章我会分享 7 个 Astro Markdown/MDX 的进阶用法,从最基础的环境配置到代码高亮、自定义组件、数学公式、流程图,每个技巧都配了完整的代码和配置步骤。读完这篇,你的技术博客能从”能看”升级到”专业”。
第一部分:基础升级 - 从 Markdown 到 MDX
为什么要用 MDX?
Markdown 和 MDX 的区别,其实就像自行车和电动车——都能骑,但体验完全不同。
纯 Markdown 只能写文本、代码块、图片这些静态内容。你想加个提示框?得用 HTML 硬编码。想在文章里嵌入一个可交互的组件?基本没戏。
MDX 就不一样了,它是”Markdown + JSX”的结合体。你可以:
- 导入和使用组件:直接在 .mdx 文件里 import 任何 Astro 组件或 React/Vue 组件
- 写 JSX 表达式:在文章里用
{variable}插入变量,甚至写循环和条件判断 - 自定义元素样式:把标准的
<h1>替换成你自己的样式化组件
举个具体例子。你想在文章里加个警告框,用纯 Markdown 得这样写:
<div class="warning">
<p>注意:这个操作会删除所有数据!</p>
</div>用 MDX 就能这样:
import Alert from '@/components/Alert.astro';
<Alert type="warning">
注意:这个操作会删除所有数据!
</Alert>看出区别了吗?MDX 让你的文章更像是在”组装积木”,而不是”写代码”。
5分钟配置 MDX 环境
配置 MDX 其实超简单,三步搞定。
第一步:安装集成包
打开终端,在你的 Astro 项目里运行:
npx astro add mdxAstro CLI 会自动帮你安装 @astrojs/mdx 并更新配置文件。这个命令会问你几个问题(要不要更新配置、要不要安装依赖),全部选 Yes 就行。
第二步:验证配置
装完后,打开 astro.config.mjs,应该能看到这样的代码:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
integrations: [mdx()],
});如果没有自动添加,手动加上就行。
第三步:测试 MDX 是否生效
在 src/pages/ 或 src/content/ 目录下创建一个 test.mdx 文件:
---
title: 测试MDX
---
# 这是 MDX 测试
普通的 Markdown 文本。
export const greeting = "你好";
现在可以用变量了:{greeting}!
<div style="padding: 1rem; background: #f0f0f0;">
这是一个 JSX 元素
</div>运行 npm run dev,访问对应页面,如果能看到变量和 JSX 元素正常显示,说明 MDX 已经配置成功了。
关于 .md 和 .mdx 文件的共存
装了 MDX 集成后,你的 .md 文件还是正常工作的,不用担心。Astro 会根据文件扩展名自动选择处理方式:
.md文件:按标准 Markdown 处理.mdx文件:按 MDX 处理,支持组件和 JSX
我的建议是:普通文章用 .md,需要用组件的文章用 .mdx。不是所有文章都需要 MDX 的能力。
第二部分:代码高亮的进阶技巧
配置代码高亮主题(Shiki)
Astro 默认用 Shiki 做代码高亮,这已经很不错了。但默认主题是 github-dark,你可能想换个更符合自己博客风格的。
Shiki vs Prism 该选哪个?
老实讲,我推荐 Shiki。它是 Astro 默认的方案,支持 100 多种编程语言和主题,而且是服务端渲染的,不需要加载额外的 JavaScript。Prism 也不错,但需要引入 CSS 文件,配置相对麻烦一点。
切换内置主题
打开 astro.config.mjs,在 markdown 配置里加上 shikiConfig:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
integrations: [mdx()],
markdown: {
shikiConfig: {
theme: 'dracula', // 可选:github-dark, nord, monokai, dracula 等
},
},
});Shiki 支持超多主题,我常用的有:
github-dark/github-light- GitHub 风格dracula- 经典的紫黑配色nord- 清冷的北欧风one-dark-pro- VSCode 默认深色主题
你可以在 Shiki 主题预览 里挑一个自己喜欢的。
实现浅色/深色双主题切换
如果你的博客支持深浅色模式切换,Shiki 可以配置双主题:
markdown: {
shikiConfig: {
themes: {
light: 'github-light',
dark: 'github-dark',
},
},
},这样配置后,Shiki 会根据 CSS 的 prefers-color-scheme 或你自定义的主题切换逻辑自动应用对应的代码高亮主题。
高亮特定行和代码注释
写教程的时候,经常需要标注”看这一行很重要”或者展示”代码改了哪些地方”。Shiki Transformers 可以实现这些功能。
高亮重点代码行
先安装 Shiki 的 transformers:
npm install shiki然后在配置里启用 transformerNotationHighlight:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import { transformerNotationHighlight } from '@shikijs/transformers';
export default defineConfig({
integrations: [mdx()],
markdown: {
shikiConfig: {
theme: 'github-dark',
transformers: [transformerNotationHighlight()],
},
},
});现在可以在代码块里用 // [!code highlight] 注释来标记需要高亮的行:
```javascript
function hello() {
console.log('这行是普通的');
console.log('这行会高亮显示'); // [!code highlight]
}
```展示代码变更(Diff 风格)
在对比”修改前/后”的代码时,可以用 transformerNotationDiff:
import { transformerNotationDiff, transformerNotationHighlight } from '@shikijs/transformers';
markdown: {
shikiConfig: {
theme: 'github-dark',
transformers: [
transformerNotationHighlight(),
transformerNotationDiff(),
],
},
},用法:
```javascript
function calculate(a, b) {
return a + b; // [!code --]
return a * b; // [!code ++]
}
```带 -- 的行会显示为红色(删除),带 ++ 的行显示为绿色(新增)。这个功能写代码教程时超级实用。
聚焦特定代码
还有一个 transformerNotationFocus,可以让其他代码”变灰”,只突出你想强调的部分:
import { transformerNotationFocus } from '@shikijs/transformers';
// 添加到 transformers 数组
transformers: [
transformerNotationFocus(),
],使用 // [!code focus] 标记:
```javascript
function process() {
console.log('这行会变灰');
console.log('这行正常显示'); // [!code focus]
console.log('这行也变灰');
}
```升级到 Expressive Code(可选)
如果你觉得 Shiki 的功能还不够,可以试试 Expressive Code。它是社区开发的增强版代码展示方案,提供了更多开箱即用的功能:
- 代码块标题
- 一键复制按钮
- 行号显示
- 终端窗口样式
- 代码对比(Side-by-Side)
安装超简单
npx astro add astro-expressive-codeAstro CLI 会自动配置好一切。装完后,你的代码块就自动带上这些功能了,不需要额外配置。
什么时候用 Expressive Code?
说实话,我一开始用的是默认的 Shiki,后来发现读者经常想复制代码,就换成了 Expressive Code。如果你的博客主要是写教程、分享代码,Expressive Code 能让读者体验好很多。
但如果只是偶尔放点代码,用 Shiki + Transformers 就够了,不用增加额外的依赖。
第三部分:嵌入自定义组件
在 MDX 中导入和使用组件
MDX 最强大的地方就是可以直接在文章里用组件。我经常用这个功能做提示框、代码对比、可折叠区域等。
创建一个警告框组件
先在 src/components/ 目录下创建一个 Alert.astro:
---
interface Props {
type?: 'info' | 'warning' | 'error';
}
const { type = 'info' } = Astro.props;
const styles = {
info: 'bg-blue-50 border-blue-200 text-blue-800',
warning: 'bg-yellow-50 border-yellow-200 text-yellow-800',
error: 'bg-red-50 border-red-200 text-red-800',
};
---
<div class={`border-l-4 p-4 ${styles[type]}`}>
<slot />
</div>在 MDX 文章中使用
在你的 .mdx 文件里导入并使用它:
---
title: 我的技术文章
---
import Alert from '@/components/Alert.astro';
# 文章标题
这是普通的文章内容。
<Alert type="warning">
注意:运行这个命令前请备份数据!
</Alert>
<Alert type="info">
提示:你也可以在组件里用 **Markdown 语法**,很方便。
</Alert>看到了吗?在 <Alert> 组件里,你还可以继续用 Markdown 语法(如加粗、链接等),MDX 会自动处理。
使用 React/Vue 组件
MDX 不仅支持 Astro 组件,也可以用 React、Vue 等框架组件。不过要注意加上 client: 指令:
import Counter from '@/components/Counter.tsx';
<Counter client:load initialCount={0} />client:load 表示这个组件会在页面加载时在客户端运行。如果不加,组件只会服务端渲染,交互功能不生效。
组件文件组织建议
我习惯把文章里常用的组件放在 src/components/mdx/ 目录下,这样好管理:
src/
├── components/
│ ├── mdx/
│ │ ├── Alert.astro
│ │ ├── CodeCompare.astro
│ │ ├── Callout.astro
│ │ └── Tabs.astro
│ └── ...其他组件映射 Markdown 语法到自定义组件
这个功能有点”黑魔法”的感觉——你可以把 Markdown 的标准元素(如 h1、a、img)替换成你自己的组件。
为什么要这么做?
比如你想给所有的标题加个锚点图标,或者给外部链接自动加个”↗“标记,手动一个个加太麻烦了。用组件映射,写标准 Markdown 就自动应用你的样式。
实战:自定义标题组件
先创建一个 CustomHeading.astro:
---
interface Props {
level: 1 | 2 | 3 | 4 | 5 | 6;
id?: string;
}
const { level, id } = Astro.props;
const Tag = `h${level}` as any;
---
<Tag id={id} class="group relative">
<slot />
{id && (
<a href={`#${id}`} class="ml-2 opacity-0 group-hover:opacity-100 transition-opacity">
#
</a>
)}
</Tag>在 MDX 中使用映射
在你的 .mdx 文件里,导出一个 components 对象:
---
title: 文章标题
---
import CustomHeading from '@/components/CustomHeading.astro';
export const components = {
h2: (props) => <CustomHeading level={2} {...props} />,
h3: (props) => <CustomHeading level={3} {...props} />,
};
## 这是二级标题
鼠标悬停在标题上,会出现 # 锚点链接。
### 这是三级标题
所有 h2 和 h3 都自动应用了自定义样式。实战:给外部链接加图标
创建 ExternalLink.astro:
---
interface Props {
href?: string;
}
const { href } = Astro.props;
const isExternal = href?.startsWith('http');
---
<a href={href} target={isExternal ? '_blank' : undefined} rel={isExternal ? 'noopener noreferrer' : undefined}>
<slot />
{isExternal && <span class="ml-1 text-xs">↗</span>}
</a>映射使用:
import ExternalLink from '@/components/ExternalLink.astro';
export const components = {
a: ExternalLink,
};
[这是内部链接](/about)
[这是外部链接](https://example.com) ← 会自动加 ↗ 图标全局配置映射(高级)
如果你想让所有 MDX 文件都用同一套组件映射,可以在 astro.config.mjs 里配置。不过这个需要自定义 MDX 插件,稍微复杂一点,我一般是在单个文件里配置就够了。
第四部分:数学公式和图表集成
集成 KaTeX 展示数学公式
如果你写算法、数学或数据科学类的文章,肯定需要展示公式。KaTeX 是目前最好的选择,比 MathJax 快很多,而且支持服务端渲染。
安装 KaTeX
需要安装三个包:
npm install remark-math rehype-katex katexremark-math:解析 LaTeX 语法rehype-katex:渲染公式为 HTMLkatex:KaTeX 核心库
配置 Astro
打开 astro.config.mjs,添加这两个插件:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
export default defineConfig({
integrations: [mdx()],
markdown: {
remarkPlugins: [remarkMath],
rehypePlugins: [rehypeKatex],
},
});引入 KaTeX 样式
这一步很重要,不然公式渲染不出来。在你的布局文件(如 src/layouts/MarkdownLayout.astro)的 <head> 里加上:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css"
crossorigin="anonymous"
/>在文章中使用公式
配置好后,就可以在 Markdown/MDX 里写公式了。
行内公式(用单个 $ 包裹):
质能方程:$E = mc^2$
二次方程的解:$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$块级公式(用双 $$ 包裹):
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$
$$
\sum_{i=1}^{n} i = \frac{n(n+1)}{2}
$$常见问题:公式不显示
如果公式不显示或样式不对,检查这几点:
- KaTeX CSS 是否正确引入(F12 看 Network 面板)
- rehype-katex 的版本是否兼容(试试降到 6.x 版本)
- 公式语法是否正确(去 KaTeX 支持列表 确认)
集成 Mermaid 绘制流程图和图表
Mermaid 可以用代码画流程图、时序图、甘特图等,特别适合技术文档。
三种集成方案对比
社区有几种 Mermaid 集成方案,我简单说说区别:
| 方案 | 渲染方式 | SEO | 配置难度 | 推荐指数 |
|---|---|---|---|---|
| rehype-mermaid | 服务端 | 好 | 中 | ⭐⭐⭐⭐⭐ |
| astro-diagram | 服务端 | 好 | 低 | ⭐⭐⭐⭐ |
| astro-mermaid | 客户端 | 差 | 低 | ⭐⭐⭐ |
我推荐 rehype-mermaid,服务端渲染,SEO 友好,生成的是静态 SVG。
安装 rehype-mermaid
npm install rehype-mermaid配置
在 astro.config.mjs 里添加:
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import rehypeMermaid from 'rehype-mermaid';
export default defineConfig({
integrations: [mdx()],
markdown: {
rehypePlugins: [
[rehypeMermaid, { strategy: 'img-svg' }]
],
},
});strategy: 'img-svg' 表示生成 SVG 图片,这是最稳定的方案。
在文章中画图
用 mermaid 代码块就行:
流程图示例:
```mermaid
graph TD
A[开始] --> B{是否安装MDX}
B -->|是| C[配置代码高亮]
B -->|否| D[安装MDX]
D --> C
C --> E[完成]
```时序图示例:
```mermaid
sequenceDiagram
用户->>浏览器: 访问页面
浏览器->>服务器: 请求HTML
服务器->>浏览器: 返回渲染后的页面
浏览器->>用户: 显示内容
```构建时生成
运行 npm run build 时,Mermaid 图表会在构建阶段生成为 SVG,最终页面里是静态图片,加载速度快,也不需要客户端 JavaScript。
注意事项
如果构建时报错”找不到 Puppeteer”,可能需要额外配置。试试安装 playwright:
npm install -D playwright或者换用 astro-diagram 方案,它内置了浏览器环境。
第五部分:高级技巧和最佳实践
Content Collections 的 MDX 优化
如果你用 Astro 的 Content Collections 管理博客文章(强烈推荐),MDX 文件可以获得更好的类型支持和开发体验。
Content Collections 是什么?
简单说,就是把文章放在 src/content/ 目录下,Astro 会自动识别、验证 frontmatter,并提供类型安全的 API 来读取内容。
配置 Content Collections
在 src/content/config.ts 定义你的集合:
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content', // 表示这是内容文件(Markdown/MDX)
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
tags: z.array(z.string()).optional(),
draft: z.boolean().default(false),
}),
});
export const collections = { blog };在 MDX 中使用
MDX 文件的 frontmatter 会被自动验证:
---
title: Astro MDX 进阶教程
description: 学习 MDX 的高级用法
pubDate: 2025-12-02
tags: [Astro, MDX, 教程]
---
import Alert from '@/components/Alert.astro';
# {frontmatter.title}
<Alert type="info">
发布日期:{frontmatter.pubDate.toLocaleDateString()}
</Alert>自动生成目录
Content Collections 提供了 getHeadings() 方法,可以获取文章的所有标题,用来生成目录:
---
import { getEntry } from 'astro:content';
const entry = await getEntry('blog', 'my-mdx-article');
const { Content, headings } = await entry.render();
---
<aside>
<h2>目录</h2>
<ul>
{headings.map(h => (
<li style={`margin-left: ${(h.depth - 1) * 1}rem`}>
<a href={`#${h.slug}`}>{h.text}</a>
</li>
))}
</ul>
</aside>
<article>
<Content />
</article>这个功能在写长文时特别实用,读者可以快速跳转到感兴趣的章节。
性能优化和常见陷阱
MDX 很强大,但用不好也会拖慢网站。这里分享几个要注意的点。
避免过度使用客户端组件
MDX 里可以用 React/Vue 组件,但别忘了加 client:* 指令。如果不加,组件只会服务端渲染,交互功能不生效;如果滥用 client:load,会增加大量 JavaScript,拖慢页面加载。
我的建议:
- 静态内容用 Astro 组件(如 Alert、Callout)
- 需要交互的用
client:visible(可见时才加载)或client:idle(空闲时加载) - 除非必要,不用
client:load
图片优化
在 MDX 里插入图片,别直接用 <img>,用 Astro 的 Image 组件:
---
title: 我的文章
---
import { Image } from 'astro:assets';
import cover from './cover.jpg';
<Image src={cover} alt="封面图" width={800} height={600} />Astro 会自动优化图片(压缩、生成 WebP、懒加载等),性能好很多。
MDX 的 optimize 选项
如果你的站点有很多 MDX 文件,构建很慢,可以试试开启 optimize 选项:
export default defineConfig({
integrations: [
mdx({
optimize: true,
}),
],
});这个选项会通过内部的 rehype 插件优化 MDX 输出,加快构建速度。不过可能会改变生成的 HTML 结构,用之前先测试一下。
常见错误和解决方案
| 错误 | 原因 | 解决方案 |
|---|---|---|
| MDX 组件不显示 | 忘了导入组件 | 检查 import 语句 |
| 交互组件不工作 | 缺少 client: 指令 | 加上 client:load 等 |
| 代码高亮不生效 | Shiki 配置错误 | 检查 astro.config.mjs |
| 数学公式不渲染 | KaTeX CSS 未引入 | 在 layout 里加 CSS 链接 |
| 构建很慢 | MDX 文件太多 | 开启 optimize 选项 |
结论
说了这么多,总结一下核心要点:
快速回顾 7 个技巧:
- 配置 MDX 环境 - 一行命令搞定,5分钟上手
- 切换代码高亮主题 - 用 Shiki 配置你喜欢的风格
- 高亮和注释代码 - 用 Transformers 标注重点、展示改动
- 嵌入自定义组件 - 让文章更生动,从 Alert 到交互式 Demo
- 映射 Markdown 元素 - 批量定制标题、链接等默认样式
- 展示数学公式 - KaTeX 让你的算法讲解更专业
- 绘制流程图 - Mermaid 用代码画图,服务端渲染
学习路径建议:
你不用一次性学完所有功能。我的建议是:
- 第一步:配置好 MDX 环境,试试导入一个简单组件
- 第二步:根据需要配置代码高亮(写代码多就配)
- 第三步:如果写算法或架构相关,再加 KaTeX 和 Mermaid
- 第四步:熟练后,再玩组件映射这种”黑魔法”
检查清单:
配置完成后,试试这些功能是否正常:
- MDX 文件能正常渲染
- 代码块有正确的高亮
- 自定义组件能显示
- 数学公式正确渲染(如果配置了)
- Mermaid 图表能生成(如果配置了)
- 构建速度可接受
下一步探索:
- 浏览 Astro Integrations 找更多有意思的插件
- 看看社区分享的 MDX 组件库
- 试试用 Astro 的 View Transitions 给博客加上流畅的页面切换动画
现在就选一个最感兴趣的功能,在你的博客上试试吧。配置过程中遇到问题也别慌,官方文档和社区都很友好,搜一下基本都能找到答案。
话说回来,技术博客最重要的还是内容本身。这些工具只是让你的表达更清晰、更专业,真正吸引读者的,是你的观点和经验。祝你的 Astro 博客越来越好!
发布于: 2025年12月2日 · 修改于: 2025年12月4日


