Next.js 中的 Markdown 与 MDX 静态内容
解释 Next.js App Router 如何把本地 Markdown/MDX 作为静态内容源,通过 @next/mdx、文件路由或导入方式参与服务端/构建时渲染,并与数据库动态内容区分。
#concept
#growing
#frame
#frontend
#react
[!info] related notes
- 所属 MOC: nextjs-moc
- 前置概念: markdown、nextjs-file-system-routing
- 并列概念:
- 易混淆概念:
- 关系笔记: nextjs-metadata-api
Next.js 中的 Markdown 与 MDX 静态内容
一句话定义
Markdown 是轻量文本格式;MDX 是可以嵌入 JSX/React 组件的 Markdown 扩展。Next.js 可以把本地 .md / .mdx 文件作为应用内容源,在构建或服务器侧转换成 React/HTML。
两种常见接入方式
文件直接成为页面
app/about/page.mdx
→ /about
MDX 可以参与 App Router 的文件系统路由,并像其他页面一样使用 Layout 与 Metadata。
在 Page 中导入内容
import Post from '@/content/post.mdx'
export default function Page() {
return <Post />
}
这更适合把“内容文件”和“路由组件”分开组织。
@next/mdx 的角色
@next/mdx 让 Next.js 构建链理解 Markdown/MDX 文件,并把它们转成 React 组件。App Router 中还需要 mdx-components.tsx 作为全局组件映射入口。
.md / .mdx
→ MDX compiler
→ React component
→ Server Component / prerender
→ HTML / RSC output
Markdown 与 MDX 的区别
Markdown
→ 文本内容 + 标记语法
MDX
→ Markdown + JSX / React components
如果只是文章、说明页、文档,普通 Markdown 往往更简单;只有需要嵌入真实 React 组件时才需要 MDX 的额外能力。
Static Content 与 Database Content
Markdown / MDX
→ content lives with code/repository
→ versioned by Git
→ often build-time / static-friendly
Database content
→ content lives in runtime data store
→ edited independently of deploy
→ queried at request/runtime
两者没有高低之分,取决于内容生命周期。
适合 Markdown/MDX:
- About / Docs
- 产品说明
- 技术文章
- 低频修改且希望 Git review 的内容
适合数据库/CMS:
- 用户生成内容
- 高频发布
- 权限与工作流复杂
- 内容更新不能依赖重新部署
Frontmatter
Frontmatter 常用于文章 metadata:
---
title: Hello
published: 2026-09-16
---
@next/mdx 本身不自动提供完整 frontmatter 工作流,通常需要额外 parser/plugin,或者直接从 MDX 文件导出 metadata 对象。
安全边界
远程、不可信 MDX 比普通 Markdown 风险更高,因为 MDX 具有执行组件/代码的能力。不要把用户提交的任意文本当可信 MDX 直接执行。
untrusted user text
→ sanitize / safe markdown renderer
≠ arbitrary MDX execution
最短记忆
Markdown = content syntax
MDX = Markdown + JSX
@next/mdx = build integration
Git-backed content ≠ runtime database content
untrusted Markdown ≠ trusted MDX code