@next/mdx
插件的主要作用是 让 Next.js 支持 MDX 文件的导入和使用。
@next/mdx
@next/mdx
是 Next.js 官方提供的一个插件,它结合了:
.md
)的简洁书写格式即:你可以在 .mdx
文件中写 Markdown 内容,也可以直接写 React 组件,比如:
# 这是一个标题
这是正文内容
<MyComponent />
使用 require('@next/mdx')
的目的是:
.mdx
文件转译为可以被 Next.js 使用的 React 组件常见的配置写法如下:
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/
})
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx']
})
require('@next/mdx')({ extension })
.mdx
文件。withMDX(...)
pageExtensions
.mdx
、.md
、.tsx
等文件扩展名。
require('@next/mdx')
的作用是让 Next.js 可以加载和渲染.mdx
文件,把它们当作 React 组件来用。
npm install @next/mdx @mdx-js/loader
next.config.js
创建或修改 next.config.js
:
// next.config.js
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
})
module.exports = withMDX({
// 支持哪些扩展名作为页面
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'],
})
.mdx
页面在 pages
目录下创建一个 .mdx
页面,比如:
touch pages/about.mdx
# 关于我们
这是一个用 **MDX** 写的页面。
你还可以使用 React 组件,比如:
<CustomMessage name="张三" />
比如你用了 <CustomMessage />
,就要在 _app.js
或 .mdx
文件中导入:
.mdx
文件中引入import CustomMessage from '../components/CustomMessage'
# 欢迎
<CustomMessage name="李四" />
_app.js
中提供(不推荐除非全局使用)mkdir components
touch components/CustomMessage.js
components/CustomMessage.js
:export default function CustomMessage({ name }) {
return <p>你好,{name},欢迎访问我们的网站!</p>
}
npm run dev
访问 http://localhost:3000/about,你将看到:
关于我们
这是一个用 MDX 写的页面。
你好,张三,欢迎访问我们的网站!
.mdx
页面写法.mdx
页面可以套用一个公共的布局(如统一导航、样式等)components/Layout.js
)// components/Layout.js
export default function Layout({ children }) {
return (
<div style={{ padding: 20, border: '1px solid #ddd' }}>
<h1>网站公共标题</h1>
<main>{children}</main>
</div>
);
}
.mdx
页面中使用这个 Layout---
layout: ../components/Layout
---
# 欢迎访问
这是一段内容。
上面这段
---
是 YAML Frontmatter,用来指定 layout。
pages/_app.js
中配置 MDX 的 layout 插件解析需要用 next-mdx-enhanced
或自己写 loader,但更推荐直接使用 MDX Component Wrapping 方案:
import Layout from '../components/Layout'
export default ({ children }) => <Layout>{children}</Layout>
# 标题
MDX 页面内容。
你也可以把 Layout 封装为默认导出的组件,.mdx
就变成一个真正的 React 组件。
Next.js 内置国际化(i18n)支持,你可以结合 .mdx
页面实现多语言切换。
next.config.js
增加 i18n
:module.exports = {
i18n: {
locales: ['en', 'zh'],
defaultLocale: 'zh',
},
}
pages/
zh/
about.mdx
en/
about.mdx
然后访问:
/zh/about
:中文页面/en/about
:英文页面next-mdx-remote
)这种方式适合动态内容渲染,比如从 CMS、文件系统、数据库读取 .mdx
内容,然后渲染为 React 页面。
npm install next-mdx-remote
pages/blog/[slug].js
):import { MDXRemote } from 'next-mdx-remote';
import { serialize } from 'next-mdx-remote/serialize';
import fs from 'fs';
import path from 'path';
export default function BlogPost({ source }) {
return (
<article>
<MDXRemote {...source} />
</article>
);
}
export async function getStaticPaths() {
const files = fs.readdirSync('posts');
const paths = files.map(file => ({
params: { slug: file.replace(/\.mdx$/, '') },
}));
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
const filepath = path.join('posts', `${params.slug}.mdx`);
const raw = fs.readFileSync(filepath, 'utf-8');
const mdxSource = await serialize(raw); // 转换为 MDX 可渲染结构
return { props: { source: mdxSource } };
}
posts/
hello.mdx
pages/
blog/
[slug].js
访问 /blog/hello
就会动态渲染出 posts/hello.mdx
内容。
方式 | 用途 | 是否支持动态内容 | 是否能嵌入组件 |
---|---|---|---|
@next/mdx |
静态页面,支持组件,配置简单 | 否 | ✅ |
带 Layout 的 MDX | 统一结构化渲染,适合文档站 | 否 | ✅ |
多语言结构 | 多语言版本页面支持 | 否 | ✅ |
next-mdx-remote |
动态渲染,适合博客/CMS场景 | ✅ | ✅ |