Astro 中的 Markdown
Markdown 通常用于创作文本繁重的内容,如博客文章和文档。Astro 包括对 Markdown 文件的内置支持,这些文件还可以包括 frontmatter YAML 来定义自定义属性,例如标题、描述和标签。
在 Astro 中,你可以在 GitHub 风格的 Markdown 中创作内容,然后在 .astro
组件中渲染它。它结合了为内容设计熟悉的书写格式、 Astro 组件语法以及架构的灵活性。
有关其他功能,例如在 Markdown 中包含组件和 JSX 表达式,请添加 @astrojs/mdx
集成以使用 MDX 编写 Markdown 内容。
组织 Markdown 文件
段落标题 组织 Markdown 文件你的本地 Markdown 文件可以保存在 src/
目录中的任何位置。要将单个本地的 Markdown 文件的导入到 .astro
组件,可以使用 import
语句来实现,而要想一次性查询多个文件,则可以使用 Vite 的 import.meta.glob()
。
如果你有一组相关的 Markdown 文件,可以考虑 将它们定义为集合。这将为你提供一些便利,其中包括了能够将 Markdown 文件存储在文件系统上的任何位置或使用远程存储。
集合还允许你使用专注于内容的优化 API 来查询和呈现你的内容。集合适用于共享相同结构的数据集,例如博客文章或产品项。当你在 schema 中定义集合时,还可以在编辑器中获得验证、类型安全和智能提示。
类 JSX 的动态表达式
段落标题 类 JSX 的动态表达式导入或查询 Markdown 文件后,你可以在 .astro
组件中编写包含 frontmatter 数据和正文内容的动态 HTML 模板。
---title: '有史以来最好的文章'author: 'Ben'---
这是我的 _很棒_ 的文章!
---import * as greatPost from '../posts/great-post.md';const posts = Object.values(await import.meta.glob('../posts/*.md', { eager: true }));---
<p>{greatPost.frontmatter.title}</p><p>作者:{greatPost.frontmatter.author}</p>
<p>文章归档:</p><ul> {posts.map(post => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}</ul>
可用属性
段落标题 可用属性查询集合
段落标题 查询集合当通过辅助函数从集合中获取数据时,Markdown 的 frontmatter 属性在 data
对象(例如 post.data.title
)上可用。此外,body
包含了 Markdown 的正文内容,这部分内容是原始的、未编译的字符串类型。
导入 Markdown
段落标题 导入 Markdown当使用 import
或 import.meta.glob()
导入 Markdown 时,以下导出的属性在你的 .astro
组件中可用:
file
- 绝对文件路径(例如/home/user/projects/.../file.md
)。url
- 如果是页面,则为页面的 URL(例如/zh-cn/guides/markdown-content
)。frontmatter
- 包含了文件的 YAML frontmatter 中所指定的任何数据。<Content />
- 返回文件完整渲染内容的组件。rawContent()
- 一个函数,将原始 Markdown 文档作为字符串返回。compiledContent()
- 一个函数,将 Markdown 文档编译为 HTML 字符串后返回。getHeadings()
- 一个异步函数,用于返回文件中所有标题(<h1>
到<h6>
)的数组,类型为:{ depth: number; slug: string; text: string }[]
。每个标题的slug
都对应了给定标题生成的 ID,可用于锚点链接。
示例 Markdown 博客文章可能会传递以下 Astro.props
对象:
Astro.props = { file: "/home/user/projects/.../file.md", url: "/en/guides/markdown-content/", frontmatter: { /** 从博客文章中获取的 Frontmatter */ title: "Astro 0.18 Release", date: "Tuesday, July 27 2021", author: "Matthew Phillips", description: "Astro 0.18 is our biggest release since Astro launch.", }, getHeadings: () => [ {"depth": 1, "text": "Astro 0.18 Release", "slug": "astro-018-release"}, {"depth": 2, "text": "Responsive partial hydration", "slug": "responsive-partial-hydration"} /* ... */ ], rawContent: () => "# Astro 0.18 Release\nA little over a month ago, the first public beta [...]", compiledContent: () => "<h1>Astro 0.18 Release</h1>\n<p>A little over a month ago, the first public beta [...]</p>",}
<Content />
组件
段落标题 <Content /> 组件<Content />
组件可通过从 Markdown 文件导入 Content
来使用。此组件返回文件的完整正文内容,并渲染为 HTML。你可以选择将 Content
重命名为你喜欢的任何组件名称。
同样,你也可以通过渲染 <Content />
组件来 渲染 Markdown 集合条目的 HTML 内容。
---// 导入语句import {Content as PromoBanner} from '../components/promoBanner.md';
// 集合查询import { getEntry, render } from 'astro:content';
const product = await getEntry('products', 'shirt');const { Content } = await render();---<h2>今日促销</h2><PromoBanner />
<p>促销截止至:{product.data.saleEndDate.toDateString()}</p><Content />
标题 ID
段落标题 标题 ID在 Markdown 中编写标题会自动为你提供锚点链接,以便你可以直接跳转到页面的某些部分。
---title: 我的文章目录---## 简介
当我使用 Markdown 时,我可以在同一个页面内链接到 [我的结论](#结论) 部分。
## 结论
我可以通过在浏览器访问 `https://example.com/page-1/#简介` 以直接导航到简介部分。
Astro 基于 github-slugger
生成标题 id
。你可以在 github-slugger 文档 中找到更多示例。
标题 ID 与插件
段落标题 标题 ID 与插件Astro 将 id
属性注入到 Markdown 和 MDX 文件中的所有标题元素(<h1>
到 <h6>
)中,并提供 getHeadings()
工具函数来检索 Markdown 导出属性 中的这些 ID。
你可以通过添加注入 id
属性的 rehype 插件(例如 rehype-slug
)来自定义这些标题 ID。你的自定义 ID 将替代 Astro 的默认 ID,反映在 HTML 输出和 getHeadings()
返回的数组中。
默认情况下,Astro 会在你的 rehype 插件运行后注入 id
属性。但如果其中一个自定义 rehype 插件需要访问 Astro 注入的 ID,你可以直接导入并使用 Astro 的 rehypeHeadingIds
插件。确保在任何依赖它的插件之前添加 rehypeHeadingIds
:
import { defineConfig } from 'astro/config';import { rehypeHeadingIds } from '@astrojs/markdown-remark';import { otherPluginThatReliesOnHeadingIDs } from 'some/plugin/source';
export default defineConfig({ markdown: { rehypePlugins: [ rehypeHeadingIds, otherPluginThatReliesOnHeadingIDs, ], },});
Markdown 插件
段落标题 Markdown 插件Astro 中的 Markdown 支持由 remark 提供,remark 是一个强大的解析和处理工具,拥有一个活跃的生态系统。目前不支持其他 Markdown 解析器,如 Pandoc 和 markdown-it。
Astro 默认应用 GitHub 风格的 Markdown 和 SmartyPants 插件。这带来了一些便利,例如从文本生成可点击的链接,并格式化引用和 em-dashes。
你可以在 astro.config.mjs
中自定义 remark 解析 Markdown 的方式。请参阅完整的 Markdown 配置选项列表。
添加 remark 和 rehype 插件
段落标题 添加 remark 和 rehype 插件Astro 支持添加第三方 remark 和 rehype 插件来解析 Markdown。这些插件允许你扩展你的 Markdown,以获得新的功能,例如 自动生成目录,应用可访问的表情符号标签,以及为你的 Markdown 添加样式。
我们鼓励你浏览 awesome-remark 和 awesome-rehype 来查看流行的插件!请参阅每个插件自己的 README 以获取特定的安装说明。
这个例子将 remark-toc
和 rehype-accessible-emojis
应用于 Markdown 文件:
import { defineConfig } from 'astro/config';import remarkToc from 'remark-toc';import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis';
export default defineConfig({ markdown: { remarkPlugins: [ [remarkToc, { heading: 'toc', maxDepth: 3 } ] ], rehypePlugins: [rehypeAccessibleEmojis], },});
自定义插件
段落标题 自定义插件为了自定义插件,请在嵌套数组中提供选项对象。
下面的示例将 标题选项添加到 remarkToc
插件 以更改目录的放置位置,并将 behavior
选项添加到 rehype-autolink-headings
插件以便在标题文本之后添加锚标记。
import remarkToc from 'remark-toc';import rehypeSlug from 'rehype-slug';import rehypeAutolinkHeadings from 'rehype-autolink-headings';
export default { markdown: { remarkPlugins: [ [remarkToc, { heading: "contents"} ] ], rehypePlugins: [rehypeSlug, [rehypeAutolinkHeadings, { behavior: 'append' }]], },}
以编程方式修改 frontmatter
段落标题 以编程方式修改 frontmatter你可以通过使用 remark 或 rehype 插件 为所有 Markdown 和 MDX 文件添加 frontmatter 属性。
-
从插件的
file
参数中将customProperty
附加到data.astro.frontmatter
属性:example-remark-plugin.mjs export function exampleRemarkPlugin() {// 所有 remark 和 rehype 插件都返回一个单独的函数return function (tree, file) {file.data.astro.frontmatter.customProperty = 'Generated property';}}添加于:astro@2.0.0
data.astro.frontmatter
包含给定 Markdown 或 MDX 文档的所有属性。这允许你修改现有的 frontmatter 属性,或者从现有的 frontmatter 计算新属性。 -
将此插件应用于你的
markdown
或mdx
集成配置:astro.config.mjs import { defineConfig } from 'astro/config';import { exampleRemarkPlugin } from './example-remark-plugin.mjs';export default defineConfig({markdown: {remarkPlugins: [exampleRemarkPlugin]},});或者
astro.config.mjs import { defineConfig } from 'astro/config';import { exampleRemarkPlugin } from './example-remark-plugin.mjs';export default defineConfig({integrations: [mdx({remarkPlugins: [exampleRemarkPlugin],}),],});
现在,每个 Markdown 或 MDX 文件都会在其 frontmatter 中有 customProperty
,使其在 导入你的 markdown 时以及从 布局中的 Astro.props.frontmatter
属性 中可用。

从 MDX 扩展 Markdown 配置
段落标题 从 MDX 扩展 Markdown 配置Astro 的 MDX 集成默认情况下会扩展你的项目的现有 Markdown 配置。要覆盖单个选项,你可以在 MDX 配置中指定它们的等效项。
下面的示例禁用了 GitHub-Flavored Markdown,并为 MDX 文件应用了不同的 remark 插件集:
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ markdown: { syntaxHighlight: 'prism', remarkPlugins: [remarkPlugin1], gfm: true, }, integrations: [ mdx({ // `syntaxHighlight` 继承自 Markdown // Markdown `remarkPlugins` 被忽略 // 仅应用 `remarkPlugin2` remarkPlugins: [remarkPlugin2], // `gfm` 覆盖为 `false` gfm: false, }) ]});
要避免从 MDX 扩展你的 Markdown 配置,请将 extendMarkdownConfig
选项 (默认开启) 设置为 false
:
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ markdown: { remarkPlugins: [remarkPlugin], }, integrations: [ mdx({ // Markdown 配置现在被忽略 extendMarkdownConfig: false, // 没有 `remarkPlugins` 应用 }) ]});
单独的 Markdown 页面
段落标题 单独的 Markdown 页面内容集合 和 将 Markdown 导入 .astro 组件 提供了更多用于渲染 Markdown 的功能,并且是处理大部分内容的推荐方法。然而,有时你可能也希望更便捷的只添加单一文件到 src/pages/
并自动为你创建一个简单的页面。
Astro 将 /src/pages/
目录 内的任何受支持的文件视为页面,包括 .md
和其他 Markdown 文件类型。
将文件放入此目录或任何子目录中,将使用文件的路径名自动构建页面路由,并显示渲染为 HTML 的 Markdown 内容。
---title: 你好,世界---
# 嗨!
这个 Markdown 文件在 `your-domain.com/page-1/` 创建了一个页面
也许没有什么样式装点,但 Markdown 还支持这个:- **加粗** 和 _斜体。_- 列表项- [链接](https://astro.build)- <p>HTML 元素</p>- 还有更多!
Frontmatter layout
属性
段落标题 Frontmatter layout 属性为了帮助扩展 Markdown 页面的有限功能,Astro 提供了一个特殊的 frontmatter layout
属性,它是 Astro Markdown 布局组件 的相对路径。如果你的 Markdown 文件位于 src/pages/
中,请创建一个布局组件并将其添加到此布局属性中,来为你的 Markdown 内容提供一个页面外壳。
---layout: ../../layouts/BlogPostLayout.astrotitle: Astro 简介author: Himanshudescription: 发现 Astro 的魅力之所在!---这是一篇使用 Markdown 编写的文章。
此布局组件是一个常规 Astro 组件,具有通过 Astro.props
为你的 Astro 模板 自动提供详细的可用属性 的功能。例如,你可以通过 Astro.props.frontmatter
访问 Markdown 文件的 frontmatter 属性:
---const {frontmatter} = Astro.props;---<html> <!-- ... --> <h1>{frontmatter.title}</h1> <h2>文章作者:{frontmatter.author}</h2> <p>{frontmatter.description}</p> <slot /> <!-- Markdown 内容被注入到这里 --> <!-- ... --></html>
你也可以在布局组件中 为你的 Markdown 设置样式。
请求远程 Markdown
段落标题 请求远程 MarkdownAstro 不包括对 实验性内容集合 之外的远程 Markdown 的内置支持!
要直接获取远程的 Markdown 并将其渲染为 HTML,你需要从 NPM 安装并配置你自己的 Markdown 解析器。这 不会 继承你配置的任何 Astro 内置 Markdown 设置。
在你的项目中实现此功能之前,请确保你了解这些限制,并考虑使用内容集合加载器来代替获取远程 Markdown。
---// 示例:从一个远程的 API 接口请求 Markdown// 并在运行时将其渲染为 HTML// 使用了 "marked" 库 (https://github.com/markedjs/marked)import { marked } from 'marked';const response = await fetch('https://raw.githubusercontent.com/wiki/adam-p/markdown-here/Markdown-Cheatsheet.md');const markdown = await response.text();const content = marked.parse(markdown);---<article set:html={content} />