Skip to content

Astro 中的 Markdown

Markdown 通常用于创作文本较多的内容,例如博客文章和文档。Astro 包括对 Markdown 文件的内置支持,这些文件还可以包括 前端 YAML 来定义自定义属性,例如标题、描述和标签。

¥Markdown is commonly used to author text-heavy content like blog posts and documentation. Astro includes built-in support for Markdown files that can also include frontmatter YAML to define custom properties such as a title, description, and tags.

在 Astro 中,你可以在 GitHub Flavored Markdown 中创作内容,然后在 .astro 组件中呈现它。这将为内容设计的熟悉的写作格式与 Astro 组件语法和架构的灵活性相结合。

¥In Astro, you can author content in GitHub Flavored Markdown, then render it in .astro components. This combines a familiar writing format designed for content with the flexibility of Astro’s component syntax and architecture.

¥Organizing Markdown files

你的本地 Markdown 文件可以保存在 src/ 目录内的任何位置。可以使用 import 语句将本地 Markdown 导入 .astro 组件,用于单个文件,并使用 Vite 的 import.meta.glob() 一次查询多个文件。

¥Your local Markdown files can be kept anywhere within your src/ directory. Local Markdown can be imported into .astro components using an import statement for a single file and Vite’s import.meta.glob() to query multiple files at once.

如果你有相关 Markdown 文件组,请考虑 将它们定义为集合。这为你带来了几个好处,包括能够将 Markdown 文件存储在文件系统的任何位置或远程。

¥If you have groups of related Markdown files, consider defining them as collections. This gives you several advantages, including the ability to store Markdown files anywhere on your filesystem or remotely.

集合还允许你使用针对内容优化的 API 来查询和呈现内容。集合适用于具有相同结构的数据集,例如博客文章或产品项目。在架构中定义该形状时,你还可以在编辑器中获得验证、类型安全和 Intellisense。

¥Collections also allow you to use content-specfic, optimized API for querying and rendering your content. Collections are intended for sets of data that share the same structure, such as blog posts or product items. When you define that shape in a schema, you additionally get validation, type safety, and Intellisense in your editor.

¥Dynamic JSX-like expressions

导入或查询 Markdown 文件后,你可以在 .astro 组件中编写包含 frontmatter 数据和正文内容的动态 HTML 模板。

¥After importing or querying Markdown files, you can write dynamic HTML templates in your .astro components that include frontmatter data and body content.

src/posts/great-post.md
---
title: 'The greatest post of all time'
author: 'Ben'
---
Here is my _great_ post!
src/pages/my-posts.astro
---
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>Written by: {greatPost.frontmatter.author}</p>
<p>Post Archive:</p>
<ul>
{posts.map(post => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
</ul>

¥Available Properties

¥Querying collections

通过辅助函数从集合中获取数据时,Markdown 的前置内容属性可在 data 对象(例如 post.data.title)上使用。此外,body 以字符串形式包含原始、未编译的正文内容。

¥When fetching data from your collections via helper functions, your Markdown’s frontmatter properties are available on a data object (e.g. post.data.title). Additionally, body contains the raw, uncompiled body content as a string.

See the full CollectionEntry type.

¥Importing Markdown

使用 importimport.meta.glob() 导入 Markdown 时,你的 .astro 组件中可以使用以下导出属性:

¥The following exported properties are available in your .astro component when importing Markdown using import or import.meta.glob():

  • file - 绝对文件路径(例如 /home/user/projects/.../file.md)。

  • url - 页面的 URL(例如 /en/guides/markdown-content)。

  • frontmatter - 包含文件 YAML 前言中指定的任何数据。

  • <Content /> - 返回文件完整渲染内容的组件。

  • rawContent() - 以字符串形式返回原始 Markdown 文档的函数。

  • compiledContent() - 返回编译为 HTML 字符串的 Markdown 文档的函数。

  • getHeadings() - 一个异步函数,返回文件中所有标题(<h1><h6>)的数组,类型为:{ depth: number; slug: string; text: string }[]。每个标题的 slug 对应于给定标题生成的 ID,可用于锚链接。

示例 Markdown 博客文章可能会传递以下 Astro.props 对象:

¥An example Markdown blog post may pass the following Astro.props object:

Astro.props = {
file: "/home/user/projects/.../file.md",
url: "/en/guides/markdown-content/",
frontmatter: {
/** Frontmatter from a blog post */
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>",
}

¥The <Content /> Component

可通过从 Markdown 文件导入 Content 来使用 <Content /> 组件。此组件返回文件的完整正文内容,呈现为 HTML。你可以选择将 Content 重命名为你喜欢的任何组件名称。

¥The <Content /> component is available by importing Content from a Markdown file. This component returns the file’s full body content, rendered to HTML. You can optionally rename Content to any component name you prefer.

你可以通过渲染 <Content /> 组件来类似地设置 渲染 HTML 内容 Markdown 集合条目

¥You can similarly render the HTML content of a Markdown collection entry by rendering a <Content /> component.

src/pages/content.astro
---
// Import statement
import {Content as PromoBanner} from '../components/promoBanner.md';
// Collections query
import { getEntry, render } from 'astro:content';
const product = await getEntry('products', 'shirt');
const { Content } = await render();
---
<h2>Today's promo</h2>
<PromoBanner />
<p>Sale Ends: {product.data.saleEndDate.toDateString()}</p>
<Content />

¥Heading IDs

在 Markdown 中编写标题会自动为你提供锚链接,以便你可以直接链接到页面的某些部分。

¥Writing headings in Markdown will automatically give you anchor links so you can link directly to certain sections of your page.

src/pages/page-1.md
---
title: My page of content
---
## Introduction
I can link internally to [my conclusion](#conclusion) on the same page when writing Markdown.
## Conclusion
I can visit `https://example.com/page-1/#introduction` in a browser to navigate directly to my Introduction.

Astro 根据 github-slugger 生成标题 id。你可以在 github-slugger 文档 中找到更多示例。

¥Astro generates heading ids based on github-slugger. You can find more examples in the github-slugger documentation.

¥Heading IDs and plugins

Astro 将 id 属性注入到 Markdown 和 MDX 文件中的所有标题元素(<h1><h6>)中,并提供 getHeadings() 实用程序来检索 Markdown 导出的属性 中的这些 ID。

¥Astro injects an id attribute into all heading elements (<h1> to <h6>) in Markdown and MDX files and provides a getHeadings() utility for retrieving these IDs in Markdown exported properties.

你可以通过添加注入 id 属性(例如 rehype-slug)的 rehype 插件来自定义这些标题 ID。你的自定义 ID(而不是 Astro 的默认值)将反映在 HTML 输出和 getHeadings() 返回的项目中。

¥You can customize these heading IDs by adding a rehype plugin that injects id attributes (e.g. rehype-slug). Your custom IDs, instead of Astro’s defaults, will be reflected in the HTML output and the items returned by getHeadings().

默认情况下,Astro 在你的 rehype 插件运行后注入 id 属性。如果你的自定义 rehype 插件之一需要访问 Astro 注入的 ID,你可以直接导入并使用 Astro 的 rehypeHeadingIds 插件。请务必在任何依赖它的插件之前添加 rehypeHeadingIds

¥By default, Astro injects id attributes after your rehype plugins have run. If one of your custom rehype plugins needs to access the IDs injected by Astro, you can import and use Astro’s rehypeHeadingIds plugin directly. Be sure to add rehypeHeadingIds before any plugins that rely on it:

astro.config.mjs
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 Plugins

Astro 中的 Markdown 支持由 remark 提供支持,remark 是一个具有活跃生态系统的强大解析和处理工具。目前不支持 Pandoc 和 markdown-it 等其他 Markdown 解析器。

¥Markdown support in Astro is powered by remark, a powerful parsing and processing tool with an active ecosystem. Other Markdown parsers like Pandoc and markdown-it are not currently supported.

Astro 默认应用 GitHub 风格的 MarkdownSmartyPants 插件。这带来了一些细节,例如从文本生成可点击的链接以及 引号和破折号 的格式。

¥Astro applies the GitHub-flavored Markdown and SmartyPants plugins by default. This brings some niceties like generating clickable links from text, and formatting for quotations and em-dashes.

你可以自定义 remark 如何解析 astro.config.mjs 中的 Markdown。查看 Markdown 配置选项 的完整列表。

¥You can customize how remark parses your Markdown in astro.config.mjs. See the full list of Markdown configuration options.

添加备注和重新炒作插件

Section titled 添加备注和重新炒作插件

¥Adding remark and rehype plugins

Astro 支持为 Markdown 添加第三方 remarkrehype 插件。这些插件允许你使用新功能扩展 Markdown,例如 自动生成目录应用可访问的表情符号标签设计你的 Markdown

¥Astro supports adding third-party remark and rehype plugins for Markdown. These plugins allow you to extend your Markdown with new capabilities, like auto-generating a table of contents, applying accessible emoji labels, and styling your Markdown.

我们鼓励你浏览 awesome-remarkawesome-rehype 寻找流行插件!有关具体安装说明,请参阅每个插件自己的自述文件。

¥We encourage you to browse awesome-remark and awesome-rehype for popular plugins! See each plugin’s own README for specific installation instructions.

此示例将 remark-tocrehype-accessible-emojis 应用于 Markdown 文件:

¥This example applies remark-toc and rehype-accessible-emojis to Markdown files:

astro.config.mjs
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],
},
});

¥Customizing a plugin

为了自定义插件,请在嵌套数组中在其后面提供一个选项对象。

¥In order to customize a plugin, provide an options object after it in a nested array.

下面的示例添加 remarkToc 插件的标题选项 以更改目录的放置位置,并添加 rehype-autolink-headings 插件的 behavior 选项 以在标题文本后添加锚标记。

¥The example below adds the heading option to the remarkToc plugin to change where the table of contents is placed, and the behavior option to the rehype-autolink-headings plugin in order to add the anchor tag after the headline text.

astro.config.mjs
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

Section titled 以编程方式修改 frontmatter

¥Modifying frontmatter programmatically

你可以使用 评论或 rehype 插件.txt 文件将 frontmatter 属性添加到所有 Markdown 和 MDX 文件中。

¥You can add frontmatter properties to all of your Markdown and MDX files by using a remark or rehype plugin.

  1. Append a customProperty to the data.astro.frontmatter property from your plugin’s file argument:

    example-remark-plugin.mjs
    export function exampleRemarkPlugin() {
    // All remark and rehype plugins return a separate function
    return function (tree, file) {
    file.data.astro.frontmatter.customProperty = 'Generated property';
    }
    }
  2. Apply this plugin to your markdown or mdx integration config:

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import { exampleRemarkPlugin } from './example-remark-plugin.mjs';
    export default defineConfig({
    markdown: {
    remarkPlugins: [exampleRemarkPlugin]
    },
    });

    or

    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,使其在 importing your markdown布局中的 Astro.props.frontmatter 属性 时可用。

¥Now, every Markdown or MDX file will have customProperty in its frontmatter, making it available when importing your markdown and from the Astro.props.frontmatter property in your layouts.

Related recipe: 添加阅读时间

从 MDX 扩展 Markdown 配置

Section titled 从 MDX 扩展 Markdown 配置

¥Extending Markdown config from MDX

Astro 的 MDX 集成将默认扩展 你项目的现有 Markdown 配置。要覆盖各个选项,你可以在 MDX 配置中指定其等效项。

¥Astro’s MDX integration will extend your project’s existing Markdown configuration by default. To override individual options, you can specify their equivalent in your MDX configuration.

以下示例禁用 GitHub 风格的 Markdown 并为 MDX 文件应用一组不同的 remark 插件:

¥The following example disables GitHub-Flavored Markdown and applies a different set of remark plugins for MDX files:

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

¥To avoid extending your Markdown config from MDX, set the extendMarkdownConfig option (enabled by default) to false:

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

¥Syntax Highlighting

Astro 内置对 志木Prisma 的支持。这提供了语法高亮:

¥Astro comes with built-in support for Shiki and Prism. This provides syntax highlighting for:

  • Markdown 或 MDX 文件中使用的所有代码围栏(“” )。

  • 内置 <Code /> 组件 中的内容(由 Shiki 提供支持)。

  • <Prism /> 组件 中的内容(由 Prism 提供支持)。

Shiki 默认启用,预先配置了 github-dark 主题。编译后的输出将仅限于内联 style,没有任何多余的 CSS 类、样式表或客户端 JS。

¥Shiki is enabled by default, preconfigured with the github-dark theme. The compiled output will be limited to inline styles without any extraneous CSS classes, stylesheets, or client-side JS.

¥Shiki configuration

Shiki 是我们默认的语法高亮器。你可以通过 shikiConfig 对象配置所有选项,如下所示:

¥Shiki is our default syntax highlighter. You can configure all options via the shikiConfig object like so:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
shikiConfig: {
// Choose from Shiki's built-in themes (or add your own)
// https://shiki.style/themes
theme: 'dracula',
// Alternatively, provide multiple themes
// See note below for using dual light/dark themes
themes: {
light: 'github-light',
dark: 'github-dark',
},
// Disable the default colors
// https://shiki.style/guide/dual-themes#without-default-color
// (Added in v4.12.0)
defaultColor: false,
// Add custom languages
// Note: Shiki has countless langs built-in, including .astro!
// https://shiki.style/languages
langs: [],
// Add custom aliases for languages
// Map an alias to a Shiki language ID: https://shiki.style/languages#bundled-languages
// https://shiki.style/guide/load-lang#custom-language-aliases
langAlias: {
cjs: "javascript"
},
// Enable word wrap to prevent horizontal scrolling
wrap: true,
// Add custom transformers: https://shiki.style/guide/transformers
// Find common transformers: https://shiki.style/packages/transformers
transformers: [],
},
},
});

¥Adding your own theme

不是使用 Shiki 的预定义主题之一,而是从本地文件导入自定义主题。

¥Instead of using one of Shiki’s predefined themes, you can import a custom theme from a local file.

astro.config.mjs
import { defineConfig } from 'astro/config';
import customTheme from './my-shiki-theme.json';
export default defineConfig({
markdown: {
shikiConfig: { theme: customTheme },
},
});

我们还建议阅读 Shiki 自己的主题文档,以了解有关主题、亮夜间模式切换或通过 CSS 变量进行样式设置的更多信息。

¥We also suggest reading Shiki’s own theme documentation to explore more about themes, light vs dark mode toggles, or styling via CSS variables.

¥Default Syntax Highlighter

如果你想默认切换到 'prism',或者完全禁用语法高亮,则可以使用 markdown.syntaxHighlighting 配置对象:

¥If you’d like to switch to 'prism' by default, or disable syntax highlighting entirely, you can use the markdown.syntaxHighlighting config object:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
// Can be 'shiki' (default), 'prism' or false to disable highlighting
syntaxHighlight: 'prism',
},
});

¥Prism configuration

如果你选择使用 Prism,Astro 将改为应用 Prism 的 CSS 类。请注意,你需要自带 CSS 样式表才能显示语法高亮!

¥If you opt to use Prism, Astro will apply Prism’s CSS classes instead. Note that you need to bring your own CSS stylesheet for syntax highlighting to appear!

  1. Choose a premade stylesheet from the available Prism Themes.

  2. Add this stylesheet to your project’s public/ directory.

  3. Load this into your page’s <head> in a layout component via a <link> tag. (See Prism basic usage.)

你还可以访问 Prism 支持的语言列表 了解选项和用法。

¥You can also visit the list of languages supported by Prism for options and usage.

¥Fetching Remote Markdown

Astro 不包括对 实验性内容集合 之外的远程 Markdown 的内置支持!

¥Astro does not include built-in support for remote Markdown outside of experimental content collections!

要直接获取远程 Markdown 并将其呈现为 HTML,你需要从 NPM 安装和配置你自己的 Markdown 解析器。这不会继承你配置的任何 Astro 内置 Markdown 设置。

¥To fetch remote Markdown directly and render it to HTML, you will need to install and configure your own Markdown parser from NPM. This will not inherit from any of Astro’s built-in Markdown settings that you have configured.

在项目中实现此功能之前,请确保你了解这些限制,并考虑使用内容集合加载器来获取远程 Markdown。

¥Be sure that you understand these limitations before implementing this in your project, and consider fetching your remote Markdown using a content collections loader instead.

src/pages/remote-example.astro
---
// Example: Fetch Markdown from a remote API
// and render it to HTML, at runtime.
// Using "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} />

¥Individual Markdown pages

Astro 将 /src/pages/ 目录内的任何受支持文件 视为页面,包括 .md 和其他 Markdown 文件类型。

¥Astro treats any supported file inside of the /src/pages/ directory as a page, including .md and other Markdown file types.

将文件放在此目录或任何子目录中,将自动使用文件的路径名构建页面路由并显示呈现为 HTML 的 Markdown 内容。

¥Placing a file in this directory, or any sub-directory, will automatically build a page route using the pathname of the file and display the Markdown content rendered to HTML.

src/pages/page-1.md
---
title: Hello, World
---
# Hi there!
This Markdown file creates a page at `your-domain.com/page-1/`
It probably isn't styled much, but Markdown does support:
- **bold** and _italics._
- lists
- [links](https://astro.build)
- <p>HTML elements</p>
- and more!

¥Frontmatter layout property

为了帮助解决 Markdown 页面的有限功能,Astro 提供了一个特殊的 frontmatter layout 属性,它是 Astro Markdown 布局组件 的相对路径。如果你的 Markdown 文件位于 src/pages/ 内,请创建一个布局组件并将其添加到此布局属性中,以在你的 Markdown 内容周围提供页面外壳。

¥To help with the limited functionality of Markdown pages, Astro provides a special frontmatter layout property which is a relative path to an Astro Markdown layout component. If your Markdown file is located within src/pages/, create a layout component and add it in this layout property to provide a page shell around your Markdown content.

src/pages/posts/post-1.md
---
layout: ../../layouts/BlogPostLayout.astro
title: Astro in brief
author: Himanshu
description: Find out what makes Astro awesome!
---
This is a post written in Markdown.

此布局组件是 Astro 模板的常规 Astro 组件,具有 特定属性自动可用Astro.props。例如,你可以通过 Astro.props.frontmatter 访问 Markdown 文件的 frontmatter 属性:

¥This layout component is a regular Astro component with specific properties automatically available through Astro.props for your Astro template. For example, you can access your Markdown file’s frontmatter properties through Astro.props.frontmatter:

src/layouts/BlogPostLayout.astro
---
const {frontmatter} = Astro.props;
---
<html>
<!-- ... -->
<h1>{frontmatter.title}</h1>
<h2>Post author: {frontmatter.author}</h2>
<p>{frontmatter.description}</p>
<slot /> <!-- Markdown content is injected here -->
<!-- ... -->
</html>

你还可以在布局组件中使用 设计你的 Markdown

¥You can also style your Markdown in your layout component.

Learn more about Markdown Layouts.
Astro 中文网 - 粤ICP备13048890号