Содержание
  1. Как устроена коллекция
  2. Почему slug обязательный
  3. Получение статей
  4. Рендер статьи
  5. Что в итоге

Блог на статическом сайте не требует базы данных и админки. Astro даёт content layer: markdown-файлы лежат в репозитории, схема проверяет frontmatter, а страницы собираются на этапе билда.

Как устроена коллекция

Коллекция описывается одним файлом src/content.config.ts. Загрузчик glob() читает markdown из папки, а schema валидирует поля через zod.

import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { z } from 'astro/zod';

const blog = defineCollection({
  loader: glob({ pattern: '**/*.md', base: './src/content/blog' }),
  schema: z.object({
    title: z.string(),
    slug: z.string(),
    pubDate: z.coerce.date(),
  }),
});

export const collections = { blog };

Главное, что даёт схема, — раннюю ошибку. Если забыть slug или указать дату строкой, сборка остановится до публикации.

Почему slug обязательный

Имя файла удобно для навигации по репозиторию, но не всегда подходит для URL. Обязательный slug отделяет одно от другого: файл может называться 2026-10-29-content-collections.md, а ссылка останется короткой — /blog/content-collections-v-astro/.

В Astro 7 glob() устроен так, что slug из frontmatter автоматически становится id записи. Дополнительный generateId не нужен.

Получение статей

getCollection() возвращает массив записей. Сортировка и фильтрация — обычный TypeScript:

const posts = await getCollection('blog');

const published = posts
  .filter((post) => !post.data.draft)
  .sort((a, b) => b.data.pubDate.getTime() - a.data.pubDate.getTime());

Для статического сайта этого достаточно: каждая статья превращается в отдельную HTML-страницу.

Рендер статьи

В динамическом маршруте render() отдаёт компонент Content и список заголовков:

---
const { Content, headings } = await render(post);
---

<article>
  <Content />
</article>

headings пригодится для оглавления. Это не отдельный плагин, а часть content layer.

Markdown остаётся текстом в git: диффы читаемые, ревью проходит как обычный код.

Что в итоге

  • контент версионируется вместе с кодом;
  • схема ловит ошибки на этапе astro check;
  • страницы остаются статическими и быстрыми;
  • для новой статьи не нужна CMS.

Дальше можно добавить теги, RSS и поиск, но база уже работает.