跳转到内容

@astrojs/ mdx

这个 Astro 集成 使得你可以使用 MDX 组件,并允许你用 .mdx 文件创建页面。

MDX 允许你在 Astro 的 Markdown 内容中使用变量、JSX 表达式和组件。如果你有已使用 MDX 编写的现有内容,此集成允许你将这些文件引入到你的 Astro 项目中。

Astro 包含一个 astro add 命令来自动设置官方集成。如果你愿意,也可以手动安装集成

在新的终端窗口中运行以下命令之一。

终端窗口
npx astro add mdx

如果你遇到任何问题,请随时在 GitHub 上向我们报告,并尝试下面的手动安装步骤。

首先,安装 @astrojs/mdx

终端窗口
npm install @astrojs/mdx

然后,使用 integrations 属性将此集成应用到你的 astro.config.* 文件中:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [mdx()],
});

要在 VS Code 中获得编辑器支持,请安装官方 MDX 扩展

对于其他编辑器,请使用 MDX 语言服务器

访问 MDX 文档以了解如何使用标准的 MDX 功能。

添加 MDX 集成可以通过 JSX 变量、表达式和组件来增强你的 Markdown 编写体验。

它还为标准 MDX 添加了额外的功能,包括支持 MDX 中的 Markdown 风格的 frontmatter。这使你可以使用 Astro 的大部分内置 Markdown 功能

.mdx 文件必须使用 MDX 语法编写,而不是 Astro 的类 HTML 语法。

要在内容集合中包含 MDX 文件,请确保你的集合加载器已配置为从 .mdx 文件加载内容

src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/blog" }),
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.coerce.date(),
})
});
export const collections = { blog };

MDX 支持使用 export 语句向 MDX 内容添加变量,或将数据导出到导入它的组件中。

例如,你可以从 MDX 页面或组件中导出一个 title 字段,并使用 {JSX 表达式} 将其用作标题

/src/blog/posts/post-1.mdx
export const title = 'My first MDX post'
# {title}

或者你可以在页面中使用 importimport.meta.glob() 语句来使用导出的 title

src/pages/index.astro
---
const matches = import.meta.glob('./posts/*.mdx', { eager: true });
const posts = Object.values(matches);
---
{posts.map(post => <p>{post.title}</p>)}

当使用 import 语句或 import.meta.glob() 时,以下属性可用于 .astro 组件

  • file - 文件的绝对路径(例如 /home/user/projects/.../file.mdx)。
  • url - 页面的 URL(例如 /zh-cn/guides/markdown-content)。
  • frontmatter - 包含文件中 YAML/TOML frontmatter 中指定的任何数据。
  • getHeadings() - 一个异步函数,返回文件中所有标题(<h1><h6>)的数组,类型为:{ depth: number; slug: string; text: string }[]。每个标题的 slug 对应于为该标题生成的 ID,可用于锚点链接。
  • <Content /> - 一个返回文件完整渲染内容的组件。
  • (任何 export 的值) - MDX 文件也可以使用 export 语句导出数据。

Astro MDX 集成默认支持在 MDX 中使用 frontmatter。你可以像在 Markdown 文件中一样添加 frontmatter 属性,这些变量可以在模板中使用,也可以在其他地方导入文件时作为命名属性使用。

/src/blog/posts/post-1.mdx
---
title: 'My first MDX post'
author: 'Houston'
---
# {frontmatter.title}
Written by: {frontmatter.author}

安装 MDX 集成后,你可以在 MDX(.mdx)文件中导入和使用 Astro 组件UI 框架组件,就像在任何其他 Astro 组件中使用它们一样。

如果需要,不要忘记在你的 UI 框架组件上包含 client:directive

MDX 文档中查看更多使用导入和导出语句的示例。

src/blog/post-1.mdx
---
title: My first post
---
import ReactCounter from '../components/ReactCounter.jsx';
I just started my new Astro blog!
Here is my counter component, working in MDX:
<ReactCounter client:load />

渲染导入的 MDX 内容时,可以通过 components prop 传递自定义组件

src/pages/page.astro
---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<!-- Creates a custom <h1> for the # syntax, _and_ applies any custom components defined in `content.mdx` -->
<Content components={{...components, h1: Heading }} />

使用 MDX,你可以将 Markdown 语法映射到自定义组件,而不是它们的标准 HTML 元素。这使你可以使用标准的 Markdown 语法编写,但对选定的元素应用特殊的组件样式。

将你的自定义组件导入到你的 .mdx 文件中,然后导出一个 components 对象,该对象将标准 HTML 元素映射到你的自定义组件

src/blog/posts/post-1.mdx
import Blockquote from '../components/Blockquote.astro';
export const components = {blockquote: Blockquote}
> This quote will be a custom Blockquote
src/components/Blockquote.astro
---
const props = Astro.props;
---
<blockquote {...props} class="bg-blue-50 p-4">
<span class="text-4xl text-blue-600 mb-2"></span>
<slot /> <!-- Be sure to add a `<slot/>` for child content! -->
</blockquote>

请访问 MDX 网站,查看可以作为自定义组件覆盖的 HTML 元素的完整列表。

安装 MDX 集成后,在 Astro 项目中使用 .mdx 文件无需额外配置。

你可以使用以下选项配置 MDX 的渲染方式

所有的 markdown 配置选项都可以在 MDX 集成中单独配置。这包括 remark 和 rehype 插件、语法高亮等等。默认情况下,这些选项将继承你的 Markdown 配置(参见 extendMarkdownConfig 选项来修改此行为)。

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import remarkToc from 'remark-toc';
import rehypePresetMinify from 'rehype-preset-minify';
export default defineConfig({
// ...
integrations: [
mdx({
syntaxHighlight: 'shiki',
shikiConfig: { theme: 'dracula' },
remarkPlugins: [remarkToc],
rehypePlugins: [rehypePresetMinify],
remarkRehype: { footnoteLabel: 'Footnotes' },
gfm: false,
}),
],
});
有关选项的完整列表,请参阅 Markdown 选项参考
  • 类型: boolean
  • 默认值: true

默认情况下,MDX 会扩展你项目的现有 Markdown 配置。要覆盖单个选项,你可以在 MDX 配置中指定它们等效的选项。

例如,假设你需要禁用 GitHub-Flavored Markdown 并为 MDX 文件应用一组不同的 remark 插件。你可以像这样应用这些选项,默认情况下 extendMarkdownConfig 是启用的

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
markdown: {
syntaxHighlight: 'prism',
remarkPlugins: [remarkPlugin1],
gfm: true,
},
integrations: [
mdx({
// `syntaxHighlight` inherited from Markdown
// Markdown `remarkPlugins` ignored,
// only `remarkPlugin2` applied.
remarkPlugins: [remarkPlugin2],
// `gfm` overridden to `false`
gfm: false,
}),
],
});

你可能还需要在 MDX 中禁用 markdown 配置扩展。为此,请将 extendMarkdownConfig 设置为 false

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
markdown: {
remarkPlugins: [remarkPlugin1],
},
integrations: [
mdx({
// Markdown config now ignored
extendMarkdownConfig: false,
// No `remarkPlugins` applied
}),
],
});

这些是直接修改输出的 estree 的插件。这对于在 MDX 文件中修改或注入 JavaScript 变量很有用。

我们建议使用 AST Explorer 来试验 estree 输出,并尝试使用 estree-util-visit 来搜索 JavaScript 节点。

  • 类型: boolean | { ignoreElementNames?: string[] }

这是一个可选的配置设置,通过内部的 rehype 插件来优化 MDX 输出,以加快构建和渲染速度。如果你有许多 MDX 文件并注意到构建速度缓慢,这可能会很有用。但是,此选项可能会生成一些未转义的 HTML,因此请确保在启用它后,你网站的交互部分仍然正常工作。

默认情况下,此功能是禁用的。要启用 MDX 优化,请将以下内容添加到你的 MDX 集成配置中

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [
mdx({
optimize: true,
}),
],
});
  • 类型: string[]

添加于: @astrojs/mdx@3.0.0

以前称为 customComponentNames

optimize 的一个可选属性,用于防止 MDX 优化器处理某些元素名称,例如通过 components prop 传递给导入的 MDX 内容的自定义组件

你需要从优化中排除这些组件,因为优化器会急切地将内容转换为静态字符串,这将破坏需要动态渲染的自定义组件。

例如,以下内容的预期 MDX 输出是在每个 "<h1>...</h1>" 的位置上输出 <Heading>...</Heading>

---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<Content components={{ ...components, h1: Heading }} />

要使用 ignoreElementNames 属性为此配置优化,请指定一个应被视为自定义组件的 HTML 元素名称数组

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
// ...
integrations: [
mdx({
optimize: {
// Prevent the optimizer from handling `h1` elements
ignoreElementNames: ['h1'],
},
}),
],
});

请注意,如果你的 MDX 文件使用 export const components = { ... } 配置自定义组件,则无需手动配置此选项。优化器将自动检测它们。

更多集成

前端框架

适配器

其他集成

贡献 社区 赞助