Astro: content collections

Astro предоставляет мощные возможности для работы с контентом через коллекции (content collections). В комбинации с библиотеками Remark и Rehype можно создавать гибкие пайплайны обработки Markdown и HTML, расширять синтаксис, добавлять плагины и формировать готовый для фронтенда контент.


Подключение и настройка Remark и Rehype

Для интеграции Remark и Rehype в Astro необходимо установить соответствующие пакеты:

npm install remark remark-html rehype rehype-stringify

Remark служит для парсинга и трансформации Markdown в AST (Abstract Syntax Tree), а Rehype работает с HTML-деревьями, позволяя выполнять сложные трансформации и вставку элементов.

В конфигурационном файле Astro (astro.config.mjs) подключение может выглядеть так:

import { defineConfig } from 'astro/config';
import remarkGfm from 'remark-gfm';
import rehypeSlug from 'rehype-slug';

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkGfm],
    rehypePlugins: [rehypeSlug],
  },
});

Ключевые моменты:

  • remarkPlugins применяются на этапе обработки Markdown.
  • rehypePlugins применяются после конвертации Markdown в HTML.
  • Плагины можно комбинировать для расширения возможностей синтаксиса.

Создание контентных коллекций в Astro

Коллекции контента (content collections) позволяют структурировать Markdown-файлы и использовать их в приложении как объекты JavaScript.

Пример структуры коллекции:

src/content/posts/
├─ first-post.md
├─ second-post.md

В src/content/config.ts определяется коллекция:

import { defineCollection, z } from 'astro:content';

const blogCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    date: z.string(),
    tags: z.array(z.string()).optional(),
  }),
});

export const collections = {
  'blog': blogCollection,
};

Markdown-файлы автоматически проходят через подключенные Remark и Rehype плагины при импорте в Astro.


Использование Remark и Rehype для расширенного синтаксиса

Remark поддерживает расширения для синтаксиса Markdown, такие как таблицы, чекбоксы и математические выражения:

import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkGfm, remarkMath],
    rehypePlugins: [rehypeSlug, rehypeKatex],
  },
});

Особенности:

  • remark-math добавляет поддержку математических формул в Markdown.
  • rehype-katex рендерит формулы в HTML с использованием KaTeX.
  • Плагины можно комбинировать без изменения структуры контентных файлов.

Пример обработки Markdown в компоненте Astro

Импорт коллекции и вывод постов с уже обработанным контентом:

---
import { getCollection } from 'astro:content';

const posts = await getCollection('blog');
---

<ul>
  {posts.map(post => (
    <li>
      <h2>{post.data.title}</h2>
      <time>{post.data.date}</time>
      <div innerHTML={post.body}></div>
    </li>
  ))}
</ul>

Ключевые моменты:

  • post.body содержит HTML-код, сгенерированный через Remark → Rehype.
  • Встраивание с помощью innerHTML позволяет рендерить весь HTML с кастомными элементами и плагинами.
  • AST можно дополнительно трансформировать перед генерацией HTML с помощью собственных Remark/Rehype плагинов.

Создание пользовательских плагинов для Remark и Rehype

Remark и Rehype поддерживают создание собственных плагинов для специфической обработки контента.

Пример простого Remark-плагина для вставки кастомных блоков:

export default function remarkCustomBlocks() {
  return (tree) => {
    visit(tree, 'paragraph', (node) => {
      if (node.children[0]?.value?.startsWith(':::note')) {
        node.type = 'html';
        node.value = `<div class="note">${node.children[0].value.slice(6)}</div>`;
      }
    });
  };
}
  • visit — функция для обхода AST.
  • Плагин преобразует специфический синтаксис :::note в HTML-блок с классом note.
  • Можно сочетать с Rehype-плагинами для дальнейшей трансформации.

Производительность и оптимизация

  • Remark и Rehype обрабатывают Markdown и HTML на этапе сборки, что минимизирует нагрузку на фронтенд.
  • Для больших коллекций контента важно использовать кеширование или предрендеринг (SSG) в Astro.
  • Можно создавать комбинации Remark → Rehype → кастомные плагины, чтобы полностью контролировать результат HTML и метаданные.

Взаимодействие с Astro Islands и динамическим контентом

Обработанный контент можно передавать в компоненты Astro Islands:

<ContentBlock html={post.body} />
  • Позволяет использовать интерактивные элементы внутри Markdown.
  • Сохраняется весь HTML, сгенерированный через Remark и Rehype.
  • Поддерживаются динамические вставки React/Vue/Svelte внутри HTML-контента через компоненты Astro.

Полезные плагины для типичных задач

  • remark-gfm — расширенный синтаксис GitHub Markdown.
  • remark-math + rehype-katex — математические формулы.
  • rehype-slug — генерация id для заголовков.
  • rehype-autolink-headings — добавление ссылок к заголовкам.
  • rehype-highlight — подсветка синтаксиса кода.

Эти плагины позволяют создавать высоко структурированные контентные коллекции и гибко управлять преобразованием Markdown в готовый HTML.