Перейти к содержимому

Markdown в Astro

Markdown часто используется для создания текстового контента, такого как посты в блогах и документация. Astro включает встроенную поддержку файлов Markdown, которые также могут содержать метаданные YAML (или TOML) для определения пользовательских свойств, таких как заголовок, описание и теги.

В Astro вы можете создавать контент в GitHub Flavored Markdown, а затем отображать его в компонентах .astro. Это сочетает привычный формат написания, предназначенный для контента, с гибкостью синтаксиса и архитектуры компонентов Astro.

Ваши локальные файлы 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.

src/pages/posts/great-post.md
---
title: 'Лучший пост всех времён'
author: 'Бен'
---
Вот мой _замечательный_ пост!
src/pages/my-posts.astro
---
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>

При получении данных из ваших коллекций с помощью хелперов getCollection() или getEntry(), метаданные вашего Markdown доступны в объекте data (например, post.data.title). Дополнительно, body содержит необработанное, несобранное содержимое body в виде строки.

Функция render() (EN) возвращает содержимое body вашего Markdown, сгенерированный список заголовков, а также изменённый объект метаданных после применения любых плагинов remark или rehype.

Следующие экспортированные свойства доступны в вашем компоненте .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 из файла Markdown. Этот компонент возвращает полное содержимое тела файла, отрендеренное в HTML. При желании вы можете переименовать Content в любое предпочитаемое имя компонента.

Аналогично вы можете отображать HTML-содержимое записи коллекции Markdown, используя компонент <Content />.

src/pages/content.astro
---
// Импорт
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 автоматически дает вам якорные ссылки, чтобы вы могли напрямую ссылаться на определённые разделы вашей страницы.

src/pages/page-1.md
---
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 добавлен перед любыми плагинами, которые зависят от него:

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 в Astro обеспечивается remark, мощным инструментом для парсинга и обработки с активной экосистемой. Другие парсеры Markdown, такие как Pandoc и markdown-it, в настоящее время не поддерживаются.

Astro по умолчанию применяет плагины GitHub-flavored Markdown и SmartyPants. Это добавляет такие удобства, как создание кликабельных ссылок из текста и форматирование для кавычек и тире.

Вы можете настроить, как remark обрабатывает ваш Markdown, в файле astro.config.mjs. См. полный список опций конфигурации Markdown (EN).

Astro поддерживает добавление сторонних плагинов remark и rehype для Markdown. Эти плагины позволяют расширить возможности вашего Markdown, например, автоматически генерировать оглавление, добавлять доступные метки для эмодзи и стилизовать ваш Markdown (EN).

Мы рекомендуем ознакомиться с awesome-remark и awesome-rehype для поиска популярных плагинов! Ознакомьтесь с README каждого плагина для получения конкретных инструкций по установке.

Этот пример применяет remark-toc и rehype-accessible-emojis к файлам Markdown:

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],
},
});

Для того чтобы настроить плагин, предоставьте после него объект options во вложенном массиве.

Пример ниже добавляет опцию heading к плагину remarkToc, чтобы изменить место размещения оглавления, и опцию behavior к плагину rehype-autolink-headings, чтобы добавить тег якоря после текста заголовка.

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' }]],
},
}

Вы можете добавить метаданные во все ваши файлы Markdown и MDX с помощью плагина remark или rehype.

  1. Добавьте customProperty к свойству data.astro.frontmatter из аргумента file вашего плагина:

    example-remark-plugin.mjs
    export function exampleRemarkPlugin() {
    // Все плагины remark и rehype возвращают отдельную функцию
    return function (tree, file) {
    file.data.astro.frontmatter.customProperty = 'Сгенерированное свойство';
    }
    }
  2. Примените этот плагин к конфигурации интеграции 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 в ваших макетах.

Связанная инструкция: Add reading time (EN)

Интеграция Astro в MDX по умолчанию расширяет существующую конфигурацию Markdown вашего проекта (EN). Чтобы отменить отдельные опции, вы можете указать их эквивалент в конфигурации MDX.

Следующий пример отключает GitHub-Flavored Markdown и применяет другой набор плагинов remark для файлов MDX:

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` унаследован от Markdown
// Игнорируются `remarkPlugins` из Markdown,
// применяется только `remarkPlugin2`.
remarkPlugins: [remarkPlugin2],
// `gfm` переопределено на `false`
gfm: false,
})
]
});

Чтобы не расширять конфигурацию Markdown из MDX, установите опцию extendMarkdownConfig (EN) (включенную по умолчанию) в false:

astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
export default defineConfig({
markdown: {
remarkPlugins: [remarkPlugin],
},
integrations: [
mdx({
// Конфигурация Markdown теперь игнорируется
extendMarkdownConfig: false,
// Не применяются `remarkPlugins`
})
]
});

Astro рассматривает любой поддерживаемый файл внутри директории /src/pages/ как страницу, включая .md и другие типы файлов Markdown.

Размещение файла в этой директории или любой поддиректории автоматически создаст маршрут страницы, используя путь к файлу, и отобразит содержимое Markdown, преобразованное в HTML. Astro автоматически добавит тег <meta charset="utf-8"> на вашу страницу для упрощения написания не-ASCII контента.

src/pages/page-1.md
---
title: Привет, мир
---
# Привет!
Этот файл Markdown создаёт страницу по адресу `your-domain.com/page-1/`
Она, возможно, не сильно стилизована, но Markdown поддерживает:
- **жирный текст** и _курсив_.
- списки
- [ссылки](https://astro.build)
- <p>HTML-элементы</p>
- и многое другое!

Чтобы компенсировать ограниченную функциональность отдельных страниц Markdown, Astro предоставляет в метаданных специальное свойство layout, которое указывает относительный путь к компоненту макета Markdown в Astro. layout не является специальным свойством при использовании коллекций контента для запроса и отображения вашего Markdown-контента и не гарантирует поддержку за пределами его предполагаемого использования.

Если ваш файл Markdown находится в src/pages/, создайте компонент макета и добавьте его в это свойство layout, чтобы предоставить оболочку страницы вокруг вашего Markdown-контента.

src/pages/posts/post-1.md
---
layout: ../../layouts/BlogPostLayout.astro
title: Кратко об Astro
author: Химаншу
description: Узнайте, что делает Astro таким потрясающим!
---
Это пост, написанный на Markdown.

Этот компонент макета — это обычный компонент Astro с определёнными свойствами, автоматически доступными через Astro.props для вашего шаблона Astro. Например, вы можете получить доступ к метаданным вашего файла Markdown через Astro.props.frontmatter:

src/layouts/BlogPostLayout.astro
---
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.

Astro не включает встроенную поддержку удалённого Markdown за пределами коллекций контента.

Чтобы загрузить удалённый Markdown напрямую и отобразить его в HTML, вам нужно будет установить и настроить собственный парсер Markdown из NPM. Это не будет наследовать никаких встроенных настроек Markdown, которые вы настроили в Astro.

Убедитесь, что вы понимаете эти ограничения перед реализацией этого в вашем проекте, и рассмотрите возможность загрузки удалённого Markdown с помощью загрузчика коллекций контента.

src/pages/remote-example.astro
---
// Пример: Получение 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} />
Внести свой вклад Сообщество Sponsor