Frontmatter — это специальный блок метаданных, который обычно
располагается в начале Markdown-файла и ограничивается тремя тире
---. Он позволяет хранить структурированную информацию,
такую как заголовок, автор, дата публикации, категории и теги. В
экосистеме JavaScript и TypeScript frontmatter активно используется
совместно с библиотеками Remark и Rehype для обработки Markdown и
последующей трансформации в HTML.
Frontmatter обычно записывается в формате YAML или JSON. Пример YAML-frontmatter:
---
title: "Пример статьи"
author: "Иван Иванов"
date: "2026-03-22"
tags:
- JavaScript
- TypeScript
- Remark
---
В TypeScript важно заранее определить структуру этих данных, чтобы избежать ошибок при их использовании в коде.
Для строгой типизации необходимо описать интерфейс, который соответствует структуре frontmatter. Например:
interface Frontmatter {
title: string;
author: string;
date: string; // Можно использовать тип Date при последующем парсинге
tags: string[];
}
Такой интерфейс позволяет TypeScript проверять корректность данных,
предотвращая случайные ошибки, например, когда tags
передаются как строка вместо массива.
Remark предоставляет плагины для работы с frontmatter. Один из
популярных — remark-frontmatter. Он позволяет извлекать
блоки frontmatter из Markdown-файлов. Пример использования:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkFrontmatter from 'remark-frontmatter';
import yaml from 'js-yaml';
const markdown = `
---
title: "Пример статьи"
author: "Иван Иванов"
date: "2026-03-22"
tags:
- JavaScript
- TypeScript
- Remark
---
# Заголовок статьи
`;
interface Frontmatter {
title: string;
author: string;
date: string;
tags: string[];
}
const processor = unified()
.use(remarkParse)
.use(remarkFrontmatter, ['yaml']);
processor.process(markdown).then((file) => {
const yamlNode = file.contents.match(/---\n([\s\S]+?)\n---/);
if (yamlNode) {
const data: Frontmatter = yaml.load(yamlNode[1]) as Frontmatter;
console.log(data.title); // "Пример статьи"
}
});
Здесь важно отметить:
remark-frontmatter только выделяет блок YAML, но не
парсит его. Для этого используется библиотека js-yaml.as Frontmatter гарантирует соответствие
структуры TypeScript-интерфейсу.Для проектов с большим количеством Markdown-файлов удобно создать универсальный утилитарный тип и функцию для загрузки frontmatter:
import fs from 'fs';
import path from 'path';
import yaml from 'js-yaml';
function loadFrontmatter<T>(filePath: string): T {
const content = fs.readFileSync(path.resolve(filePath), 'utf-8');
const match = content.match(/---\n([\s\S]+?)\n---/);
if (!match) throw new Error('Frontmatter не найден');
return yaml.load(match[1]) as T;
}
// Использование
interface PostFrontmatter {
title: string;
author: string;
date: string;
tags: string[];
}
const postData = loadFrontmatter<PostFrontmatter>('./posts/example.md');
console.log(postData.date);
Такой подход позволяет строго контролировать соответствие данных, избегая ошибок при дальнейшей обработке Markdown.
После парсинга Markdown и извлечения frontmatter часто возникает необходимость трансформировать контент в HTML. Для этого используется Rehype:
import rehypeStringify from 'rehype-stringify';
import remark2rehype from 'remark-rehype';
import { unified } from 'unified';
import remarkParse from 'remark-parse';
const content = `
# Заголовок статьи
`;
unified()
.use(remarkParse)
.use(remark2rehype)
.use(rehypeStringify)
.process(content)
.then((file) => {
console.log(String(file));
});
Типизация frontmatter позволяет отделить метаданные от контента и безопасно передавать их в шаблоны или API. Обычно frontmatter хранится отдельно от HTML-контента, но совместная типизация обеспечивает согласованность данных в проекте.
title,
date) до использования. TypeScript не проверяет фактическое
содержание YAML, поэтому runtime-валидация помогает избежать
ошибок.Date для удобства сортировки и форматирования.Типизация frontmatter в TypeScript вместе с Remark и Rehype позволяет создавать надежные и безопасные инструменты для генерации статического контента, автоматической документации и блог-платформ, минимизируя ошибки на этапе разработки.