Markdown в Astro
Markdown часто используется для создания текстового контента, такого как посты в блогах и документация. Astro включает встроенную поддержку файлов Markdown, которые также могут содержать метаданные YAML (или TOML) для определения пользовательских свойств, таких как заголовок, описание и теги.
В Astro вы можете создавать контент в GitHub Flavored Markdown, а затем отображать его в компонентах .astro
. Это сочетает привычный формат написания, предназначенный для контента, с гибкостью синтаксиса и архитектуры компонентов Astro.
Для дополнительной функциональности, такой как включение компонентов и выражений JSX в Markdown, добавьте интеграцию @astrojs/mdx
(EN), чтобы писать ваш Markdown-контент с использованием MDX.
Организация файлов Markdown
Заголовок раздела Организация файлов MarkdownВаши локальные файлы Markdown могут находиться в любом месте внутри директории src/
. Файлы Markdown, расположенные в src/pages/
, автоматически генерируют страницы Markdown на вашем сайте.
Ваш Markdown-контент и метаданные доступны для использования в компонентах через импорт локальных файлов или при запросе и отображении данных, полученных с помощью функций-хелперов коллекций контента.
Импорт файлов в сравнении с запросами коллекций контента
Заголовок раздела Импорт файлов в сравнении с запросами коллекций контентаЛокальные файлы Markdown можно импортировать в компонентах .astro
с использованием оператора import
для одного файла и функции import.meta.glob()
от Vite (EN) для запроса нескольких файлов одновременно. Экспортированные данные из этих файлов Markdown затем можно использовать в компоненте .astro
.
Если у вас есть группы связанных файлов Markdown, рассмотрите возможность определения их как коллекций. Это даёт несколько преимуществ, включая возможность хранить файлы Markdown в любом месте файловой системы или удалённо.
Коллекции используют специализированные API для запроса и отображения вашего Markdown-контента вместо импорта файлов. Коллекции предназначены для наборов данных, которые имеют одинаковую структуру, например, посты в блогах или товары. Когда вы определяете эту структуру в схеме, вы также получаете валидацию, типобезопасность и IntelliSense в вашем редакторе.
Динамические выражения, похожие на JSX
Заголовок раздела Динамические выражения, похожие на JSXПосле импорта или запроса файлов Markdown вы можете писать динамические HTML-шаблоны в ваших компонентах .astro
, включая метаданные и содержимое body
.
---title: 'Лучший пост всех времён'author: 'Бен'---
Вот мой _замечательный_ пост!
---import * as greatPost from './posts/great-post.md';const posts = Object.values(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 из запросов коллекций контента
Заголовок раздела Markdown из запросов коллекций контентаПри получении данных из ваших коллекций с помощью хелперов getCollection()
или getEntry()
, метаданные вашего Markdown доступны в объекте data
(например, post.data.title
). Дополнительно, body
содержит необработанное, несобранное содержимое body
в виде строки.
Функция render()
(EN) возвращает содержимое body
вашего Markdown, сгенерированный список заголовков, а также изменённый объект метаданных после применения любых плагинов remark или rehype.
Импорт Markdown
Заголовок раздела Импорт MarkdownСледующие экспортированные свойства доступны в вашем компоненте .astro
при импорте Markdown с использованием import
или import.meta.glob()
:
file
— Абсолютный путь к файлу (например,/home/user/projects/.../file.md
).url
— URL страницы (например,/en/guides/markdown-content
).frontmatter
— Содержит любые данные, указанные в метаданных YAML (или TOML) файла.<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: { /** Метаданные из поста блога */ 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 />
доступен при импорте Content
из файла Markdown. Этот компонент возвращает полное содержимое тела файла, отрендеренное в HTML. При желании вы можете переименовать Content
в любое предпочитаемое имя компонента.
Аналогично вы можете отображать HTML-содержимое записи коллекции Markdown, используя компонент <Content />
.
---// Импортimport {Content as PromoBanner} from '../components/promoBanner.md';
// Запрос коллекцииimport { getEntry, render } from 'astro:content';
const product = await getEntry('products', 'shirt');const { Content } = await render(product);---<h2>Сегодняшняя акция</h2><PromoBanner />
<p>Акция заканчивается: {product.data.saleEndDate.toDateString()}</p><Content />
Идентификаторы заголовков
Заголовок раздела Идентификаторы заголовковИспользование заголовков в Markdown и MDX автоматически дает вам якорные ссылки, чтобы вы могли напрямую ссылаться на определённые разделы вашей страницы.
---title: Моя страница с контентом---## Введение
Я могу ссылаться внутри страницы на [мое заключение](#заключение) при написании Markdown.
## Заключение
Я могу перейти по ссылке `https://example.com/page-1/#введение` в браузере, чтобы сразу перейти к разделу «Введение».
Astro генерирует id
заголовков на основе github-slugger
. Больше примеров вы можете найти в документации github-slugger.
Идентификаторы заголовков и плагины
Заголовок раздела Идентификаторы заголовков и плагиныAstro добавляет атрибут id
во все элементы заголовков (<h1>
до <h6>
) в файлах Markdown и MDX. Вы можете получить эти данные с помощью утилиты getHeadings()
, доступной как экспортированное свойство Markdown из импортированного файла, или через функцию render()
при использовании Markdown, возвращённого запросом коллекций контента.
Вы можете настроить эти идентификаторы заголовков, добавив плагин rehype, который внедряет атрибуты id
(например, rehype-slug
). Ваши пользовательские идентификаторы, вместо стандартных значений Astro, будут отражены в HTML-выводе и элементах, возвращаемых getHeadings()
.
По умолчанию Astro добавляет атрибуты id
после выполнения ваших плагинов rehype. Если один из ваших пользовательских плагинов rehype нуждается в доступе к ID, добавленным Astro, вы можете импортировать и использовать плагин rehypeHeadingIds
от Astro напрямую. Убедитесь, что 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Поддержка Markdown в Astro обеспечивается remark, мощным инструментом для парсинга и обработки с активной экосистемой. Другие парсеры Markdown, такие как Pandoc и markdown-it, в настоящее время не поддерживаются.
Astro по умолчанию применяет плагины GitHub-flavored Markdown и SmartyPants. Это добавляет такие удобства, как создание кликабельных ссылок из текста и форматирование для кавычек и тире.
Вы можете настроить, как remark обрабатывает ваш Markdown, в файле astro.config.mjs
. См. полный список опций конфигурации Markdown (EN).
Добавление remark и rehype плагинов
Заголовок раздела Добавление remark и rehype плагиновAstro поддерживает добавление сторонних плагинов remark и rehype для Markdown. Эти плагины позволяют расширить возможности вашего Markdown, например, автоматически генерировать оглавление, добавлять доступные метки для эмодзи и стилизовать ваш Markdown (EN).
Мы рекомендуем ознакомиться с 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], },});
Настройка плагина
Заголовок раздела Настройка плагинаДля того чтобы настроить плагин, предоставьте после него объект options
во вложенном массиве.
Пример ниже добавляет опцию heading
к плагину 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' }]], },}
Программное изменение метаданных
Заголовок раздела Программное изменение метаданныхВы можете добавить метаданные во все ваши файлы Markdown и MDX с помощью плагина remark или rehype.
-
Добавьте
customProperty
к свойствуdata.astro.frontmatter
из аргументаfile
вашего плагина:example-remark-plugin.mjs export function exampleRemarkPlugin() {// Все плагины remark и rehype возвращают отдельную функциюreturn function (tree, file) {file.data.astro.frontmatter.customProperty = 'Сгенерированное свойство';}}Добавлено в:astro@2.0.0
data.astro.frontmatter
содержит все свойства данного документа Markdown или MDX. Это позволяет изменять существующие метаданные или вычислять новые свойства из существующих метаданных. -
Примените этот плагин к конфигурации интеграции
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 будет содержать customProperty
в своих метаданных, что делает его доступным при импорте вашего markdown и из свойства Astro.props.frontmatter
в ваших макетах.

Расширение конфигурации Markdown из MDX
Заголовок раздела Расширение конфигурации Markdown из MDXИнтеграция Astro в MDX по умолчанию расширяет существующую конфигурацию Markdown вашего проекта (EN). Чтобы отменить отдельные опции, вы можете указать их эквивалент в конфигурации MDX.
Следующий пример отключает GitHub-Flavored Markdown и применяет другой набор плагинов remark для файлов MDX:
import { defineConfig } from 'astro/config';import mdx from '@astrojs/mdx';
export default defineConfig({ markdown: { syntaxHighlight: 'prism', remarkPlugins: [remarkPlugin1], gfm: true, }, integrations: [ mdx({ // `syntaxHighlight` унаследован от Markdown
// Игнорируются `remarkPlugins` из Markdown, // применяется только `remarkPlugin2`. remarkPlugins: [remarkPlugin2], // `gfm` переопределено на `false` gfm: false, }) ]});
Чтобы не расширять конфигурацию Markdown из MDX, установите опцию extendMarkdownConfig
(EN) (включенную по умолчанию) в 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.
Размещение файла в этой директории или любой поддиректории автоматически создаст маршрут страницы, используя путь к файлу, и отобразит содержимое Markdown, преобразованное в HTML. Astro автоматически добавит тег <meta charset="utf-8">
на вашу страницу для упрощения написания не-ASCII контента.
---title: Привет, мир---
# Привет!
Этот файл Markdown создаёт страницу по адресу `your-domain.com/page-1/`
Она, возможно, не сильно стилизована, но Markdown поддерживает:- **жирный текст** и _курсив_.- списки- [ссылки](https://astro.build)- <p>HTML-элементы</p>- и многое другое!
Свойство layout
Заголовок раздела Свойство layoutЧтобы компенсировать ограниченную функциональность отдельных страниц Markdown, Astro предоставляет в метаданных специальное свойство layout
, которое указывает относительный путь к компоненту макета Markdown в Astro. layout
не является специальным свойством при использовании коллекций контента для запроса и отображения вашего Markdown-контента и не гарантирует поддержку за пределами его предполагаемого использования.
Если ваш файл Markdown находится в src/pages/
, создайте компонент макета и добавьте его в это свойство layout
, чтобы предоставить оболочку страницы вокруг вашего Markdown-контента.
---layout: ../../layouts/BlogPostLayout.astrotitle: Кратко об Astroauthor: Химаншуdescription: Узнайте, что делает Astro таким потрясающим!---Это пост, написанный на Markdown.
Этот компонент макета — это обычный компонент Astro с определёнными свойствами, автоматически доступными через Astro.props
для вашего шаблона Astro. Например, вы можете получить доступ к метаданным вашего файла Markdown через Astro.props.frontmatter
:
---const {frontmatter} = Astro.props;---<html> <head> <!-- ... --> <meta charset="utf-8"> <!-- больше не добавляется по умолчанию --> </head> <!-- ... --> <h1>{frontmatter.title}</h1> <h2>Автор поста: {frontmatter.author}</h2> <p>{frontmatter.description}</p> <slot /> <!-- Содержимое Markdown вставляется здесь --> <!-- ... --></html>
При использовании свойства фронтматера layout
вы должны включить тег <meta charset="utf-8">
в ваш макет, так как Astro больше не добавляет его автоматически. Теперь вы также можете стилизовать ваш Markdown (EN) в вашем компоненте макета.
Получение удалённого Markdown
Заголовок раздела Получение удалённого MarkdownAstro не включает встроенную поддержку удалённого Markdown за пределами коллекций контента.
Чтобы загрузить удалённый Markdown напрямую и отобразить его в HTML, вам нужно будет установить и настроить собственный парсер Markdown из NPM. Это не будет наследовать никаких встроенных настроек Markdown, которые вы настроили в Astro.
Убедитесь, что вы понимаете эти ограничения перед реализацией этого в вашем проекте, и рассмотрите возможность загрузки удалённого Markdown с помощью загрузчика коллекций контента.
---// Пример: Получение Markdown с удалённого API// и рендеринг его в 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} />