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

Markdown и MDX

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

С интеграцией @astrojs/mdx Astro также поддерживает файлы MDX (.mdx), которые добавляют дополнительные функции, такие как поддержка JavaScript-выражений и компонентов в вашем Markdown-контенте.

Используйте один или оба типа файлов для написания материалов в формате Markdown!

Вы можете управлять своими файлами Markdown и MDX в Astro в специальной папке src/content/. Коллекции контента помогут вам организовать контент, проверить frontmatter и обеспечить автоматическую безопасность типов TypeScript при работе с контентом.

  • Директорияsrc/content/
    • Директорияnewsletter/
      • week-1.md
      • week-2.md
    • Директорияauthors/
      • grace-hopper.md
      • alan-turing.md

Узнайте больше об использовании коллекций контента в Astro.

Astro рассматривает любой файл .md (или другое поддерживаемое расширение) или .mdx внутри директории /src/pages/ как страницу.

Помещение файла в эту директорию или любую поддиректорию автоматически построит маршрут страницы по имени файла.

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)
- and more!
Читайте больше о файловой маршрутизации или о возможностях создания динамических маршрутов в Astro.

Astro предоставляет некоторые дополнительные, встроенные функции Markdown, доступные при использовании Markdown и MDX файлов.

Astro предоставляет страницам Markdown и MDX (расположенным в src/pages/) специальное свойство frontmatter layout, которое может указывать относительный путь (или псевдоним) к компоненту макета Astro.

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.props. Например, вы можете получить доступ к свойствам frontmatter через 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 в своем компоненте макета.

Узнайте больше о Макетах Markdown.

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

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 use the URL `https://example.com/page-1/#introduction` to navigate directly to my Introduction on the page.

Astro генерирует id заголовков на основе github-slugger. Больше примеров вы можете найти в документации github-slugger.

Некоторые символы имеют особое значение в Markdown и MDX. Для их отображения может потребоваться другой синтаксис. Для этого вы можете использовать HTML entities для этих символов.

Например, чтобы < не интерпретировался как начало HTML-элемента, напишите &lt;. Или, чтобы { не интерпретировался как начало выражения JavaScript в MDX, напишите &lcub;.

Добавление интеграции MDX от Astro обогащает вашу работу с Markdown переменными JSX, выражениями и компонентами.

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

Файлы .mdx должны быть написаны на синтаксисе MDX, а не на HTML-подобном синтаксисе Astro.

Использование экспортируемых переменных в MDX

Заголовок раздела Использование экспортируемых переменных в MDX

MDX поддерживает использование операторов export для добавления переменных в содержимое MDX. Эти переменные доступны как в самом шаблоне, так и в виде именованных свойств при импорте файла куда-либо еще.

Например, вы можете экспортировать поле title из MDX-страницы или компонента, чтобы использовать его в качестве заголовка с помощью {JSX-выражений}:

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

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

/src/pages/posts/post-1.mdx
---
layout: '../../layouts/BlogPostLayout.astro'
title: 'My first MDX post'
---
# {frontmatter.title}

После установки интеграции MDX вы можете импортировать и использовать как компоненты Astro, так и компоненты UI-фреймворка в файлах MDX (.mdx) так же, как вы бы использовали их в любом другом компоненте Astro.

Не забудьте включить директиву client:directive в ваши компоненты UI-фреймворка, если это необходимо!

Дополнительные примеры использования операторов import и export можно найти в документации по MDX.

src/pages/about.mdx
---
layout: ../layouts/BaseLayout.astro
title: About me
---
import Button from '../components/Button.astro';
import ReactCounter from '../components/ReactCounter.jsx';
I live on **Mars** but feel free to <Button title="Contact me" />.
Here is my counter component, working in MDX:
<ReactCounter client:load />

Присвоение пользовательских компонентов элементам HTML

Заголовок раздела Присвоение пользовательских компонентов элементам HTML

С помощью MDX вы можете назначать синтаксис Markdown пользовательским компонентам вместо их стандартных HTML-элементов. Это позволяет вам писать в стандартном синтаксисе Markdown, но применять специальные стили компонентов к выбранным элементам.

Импортируйте свой пользовательский компонент в файл .mdx, затем экспортируйте объект components, который сопоставляет стандартный элемент HTML с вашим пользовательским компонентом:

src/pages/about.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 /> <!-- Обязательно добавьте `<slot/>` для дочернего контента! -->
</blockquote>

Посетите сайт MDX для получения полного списка HTML-элементов, которые могут быть перезаписаны как пользовательские компоненты.

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

Вы можете импортировать одну конкретную страницу с помощью оператора import или несколько страниц с помощью Astro.glob().

src/pages/index.astro
---
// Импорт одного файла
import * as myPost from '../pages/post/my-post.md';
// Импорт нескольких файлов с помощью Astro.glob
const posts = await Astro.glob('../pages/post/*.md');
---

Когда вы импортируете Markdown и MDX файлы в компонент Astro, вы получаете объект, содержащий их экспортированные свойства.

/src/pages/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 '../pages/post/great-post.md';
const posts = await Astro.glob('../pages/post/*.md');
---
<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>

В MDX-файлах вы можете получить доступ к свойствам как из операторов frontmatter, так и из операторов export:

/src/pages/posts/mdx-post.mdx
---
title: 'The greatest post of all time'
author: 'Ben'
---
export const description = 'Get comfortable! This is going to be a great read.'
Here is my _great_ post!
src/pages/my-posts.astro
---
import * as greatPost from '../pages/post/mdx-post.mdx';
---
<p>{greatPost.frontmatter.title}</p>
<p>Written by: {greatPost.frontmatter.author}</p>
<p>{greatPost.description}</p>

Вы можете дополнительно указать тип для переменной frontmatter, используя обобщённый тип TypeScript:

src/pages/index.astro
---
interface Frontmatter {
title: string;
description?: string;
}
const posts = await Astro.glob<Frontmatter>('../pages/post/*.md');
---
<ul>
{posts.map(post => <li>{post.frontmatter.title}</li>)}
<!-- post.frontmatter.title will be `string`! -->
</ul>

Следующие свойства доступны компоненту .astro при использовании оператора import или Astro.glob():

  • file - Абсолютный путь к файлу (например, /home/user/projects/.../file.md).
  • url - Если это страница, то URL страницы (например, /ru/guides/markdown-content).
  • frontmatter - Содержит любые данные, указанные в YAML frontmatter файла.
  • getHeadings - Асинхронная функция, возвращающая массив всех заголовков (т.е. элементов h1 -> h6) в файле. slug каждого заголовка соответствует сгенерированному идентификатору для данного заголовка и может использоваться для якорных ссылок. Этот список имеет вид: { depth: number; slug: string; text: string }[].
  • Content - компонент, который возвращает полное, отрендеренное содержимое файла.
  • (только для Markdown) rawContent() - Функция, возвращающая необработанный документ Markdown в виде строки.
  • (только Markdown) compiledContent() - Функция, возвращающая документ Markdown, скомпилированный в строку HTML. Обратите внимание, что сюда не входят макеты, настроенные в вашем frontmatter! Будет возвращен только сам документ Markdown в виде HTML.
  • (только MDX) - MDX-файлы также могут экспортировать данные с помощью оператора export.

Импортируйте Content, чтобы создать компонент, возвращающий полное содержимое Markdown или MDX-файла:

src/pages/content.astro
---
import {Content as PromoBanner} from '../components/promoBanner.md';
---
<h2>Today's promo</h2>
<PromoBanner />

Пример: Динамическая маршрутизация страниц

Заголовок раздела Пример: Динамическая маршрутизация страниц

Вместо того чтобы помещать файлы Markdown/MDX в каталог src/pages/ для создания маршрутов страниц, вы можете генерировать страницы динамически.

Чтобы получить доступ к содержимому в формате Markdown, передайте компонент <Content/> через props страницы Astro. Затем вы можете получить компонент из Astro.props и отобразить его в шаблоне страницы.

src/pages/[slug].astro
---
export async function getStaticPaths() {
const posts = await Astro.glob('../posts/**/*.md')
return posts.map(post => ({
params: {
slug: post.frontmatter.slug
},
props: {
post
},
}))
}
const { Content } = Astro.props.post
---
<article>
<Content/>
</article>

MDX-файлы также могут экспортировать данные с помощью оператора export.

Например, вы можете экспортировать поле title из MDX-страницы или компонента.

/src/pages/posts/post-1.mdx
export const title = 'My first MDX post'

Этот title будет доступен из операторов import и Astro.glob():

src/pages/index.astro
---
const posts = await Astro.glob('./*.mdx');
---
{posts.map(post => <p>{post.title}</p>)}

Пользовательские компоненты с импортированным MDX

Заголовок раздела Пользовательские компоненты с импортированным MDX

При рендеринге импортированного MDX-контента пользовательские компоненты могут быть переданы через свойство components.

src/pages/page.astro
---
import { Content, components } from '../content.mdx';
import Heading from '../Heading.astro';
---
<!-- Создает пользовательский <h1> для синтаксиса #, _и_ применяет любые пользовательские компоненты, определенные в `content.mdx` -->
<Content components={{...components, h1: Heading }} />

Поддержка Markdown в Astro осуществляется с помощью remark, мощного инструмента для разбора и обработки с активной экосистемой. Другие парсеры Markdown, такие как Pandoc и markdown-it, в настоящее время не поддерживаются.

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

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

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

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

В этом примере remark-toc и rehype-accessible-emojis применяются как к Markdown, так и к MDX-файлам:

astro.config.mjs
import { defineConfig } from 'astro/config';
import remarkToc from 'remark-toc';
import { rehypeAccessibleEmojis } from 'rehype-accessible-emojis';
export default defineConfig({
markdown: {
// Применяется к файлам .md и .mdx
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeAccessibleEmojis],
},
});

Обратите внимание, что по умолчанию remarkToc требует наличия на странице заголовка “ToC” или “Table of Contents” heading (без учета регистра), чтобы показать оглавление.

Astro внедряет атрибут id во все элементы заголовков (от <h1> до <h6>) в файлах Markdown и MDX и предоставляет утилиту getHeadings() для извлечения этих идентификаторов в экспортируемых свойствах Markdown.

Вы можете настроить эти идентификаторы заголовков, добавив плагин rehype, который вводит атрибуты id (например, rehype-slug). Ваши пользовательские идентификаторы, вместо установленных Astro по умолчанию, будут отражаться в HTML-выводе и элементах, возвращаемых функцией getHeadings().

По умолчанию Astro вводит атрибуты id после запуска ваших плагинов rehype. Если одному из ваших собственных плагинов rehype нужен доступ к идентификаторам, вводимым Astro, вы можете импортировать и использовать плагин Astro rehypeHeadingIds напрямую. Обязательно добавьте 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,
],
},
});

Для того чтобы настроить плагин, предоставьте после него объект 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' }]],
},
}

Вы можете добавить свойства frontmatter во все ваши файлы 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 = 'Generated property';
    }
    }
  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 в своем frontmatter, что делает его доступным при импорте вашего markdown и из свойства Astro.props.frontmatter в ваших макетах.

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

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

Следующий пример отключает GitHub-Flavored Markdown и применяет другой набор плагинов ремарок для файлов 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 (включенную по умолчанию) в 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 поставляется со встроенной поддержкой Shiki и Prism. Это обеспечивает подсветку синтаксиса для:

Shiki включена по умолчанию, предварительно настроена на тему github-dark. Компилируемый вывод будет ограничен встроенным style без посторонних CSS-классов, таблиц стилей или клиентского JS.

Shiki - это наш инструмент подсветки синтаксиса по умолчанию. Вы можете настроить все параметры через объект shikiConfig следующим образом:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
shikiConfig: {
// Выберите одну из встроенных тем Shiki (или добавьте свою)
// https://shiki.style/themes
theme: 'dracula',
// Как вариант, укажите несколько тем
// https://shiki.style/guide/dual-themes
themes: {
light: 'github-light',
dark: 'github-dark',
},
// Добавляем пользовательские языки
// Примечание: В Shiki встроено бесчисленное множество языков, включая .astro!
// https://shiki.style/languages
langs: [],
// Включите перенос слов, чтобы избежать горизонтальной прокрутки
wrap: true,
// Добавьте пользовательские transformers: https://shiki.style/guide/transformers
// Найдите общие transformers: https://shiki.style/packages/transformers
transformers: [],
},
},
});

Вместо того чтобы использовать одну из предопределенных тем Shiki, вы можете импортировать собственную тему из локального файла.

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

Мы также рекомендуем прочитать документацию по темам Shiki, чтобы узнать больше о темах, переключателях светлого и темного режимов, а также о стилизации с помощью переменных CSS.

Изменение режима подсветки синтаксиса по умолчанию

Заголовок раздела Изменение режима подсветки синтаксиса по умолчанию

Если вы хотите переключиться на режим 'prism' по умолчанию или полностью отключить подсветку синтаксиса, вы можете использовать объект конфигурации markdown.syntaxHighlighting:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
markdown: {
// Может быть 'shiki' (по умолчанию), 'prism' или false для отключения подсветки
syntaxHighlight: 'prism',
},
});

Если вы решили использовать Prism, Astro будет применять CSS-классы Prism. Обратите внимание, что вам нужно принести свою собственную таблицу стилей CSS, чтобы появилась подсветка синтаксиса!

  1. Выберите готовую таблицу стилей из доступных тем Prism.
  2. Добавьте эту таблицу стилей в директорию public/ вашего проекта.
  3. Загрузите ее в <head> вашей страницы через компонент макета с помощью тега <link>. (См. Базовое использование Prism.)

Вы также можете посетить список языков, поддерживаемых Prism для получения информации о возможностях и использовании.

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

Astro не включает встроенную поддержку удаленного Markdown! Чтобы получить удаленный Markdown и преобразовать его в HTML, вам нужно установить и настроить свой собственный парсер Markdown из npm. Он не будет наследоваться от встроенных в Astro настроек Markdown и MDX, которые вы настроили. Убедитесь, что вы понимаете эти ограничения, прежде чем внедрять его в свой проект.

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} />