Переводы метаданных

MDX (Markdown + JSX) позволяет объединять возможности обычного Markdown с компонентами React, предоставляя гибкий способ структурирования контента. Одной из ключевых особенностей MDX является работа с метаданными, которые часто используются для описания документа, его свойств или контекста. Метаданные в MDX хранятся в виде frontmatter — блока YAML в начале файла.

---
title: "Пример документа"
author: "Иван Иванов"
date: "2026-03-23"
tags: ["MDX", "JavaScript", "Метаданные"]
---

Чтение метаданных

MDX автоматически экспортирует frontmatter как объект metadata или frontmatter. При интеграции с Next.js или Gatsby эти данные доступны для дальнейшей обработки:

import { useMDXComponent } from 'next-contentlayer/hooks';
import { allPosts } from '.contentlayer/data';

export function Post({ post }) {
  const Component = useMDXComponent(post.body.code);
  return (
    <>
      <h1>{post.title}</h1>
      <p>Автор: {post.author}</p>
      <Component />
    </>
  );
}

Здесь post содержит весь frontmatter вместе с содержимым MDX. Ключевой момент: frontmatter преобразуется в объект JavaScript и может быть использован для динамического рендеринга компонентов.

Локализация метаданных

Для приложений с мультиязычностью важно уметь переводить метаданные. Один из подходов — хранение локализованных версий frontmatter:

---
title:
  ru: "Пример документа"
  en: "Document Example"
author: "Иван Иванов"
date: "2026-03-23"
tags: ["MDX", "JavaScript", "Metadata"]
---

В коде выбор локали может выглядеть следующим образом:

const locale = 'ru'; // динамически выбирается в зависимости от пользователя
const localizedTitle = post.title[locale] || post.title.en;

Такой подход позволяет хранить несколько языковых версий прямо в frontmatter и не менять структуру MDX-файлов.

Динамическая генерация метаданных

Иногда требуется автоматически добавлять или изменять метаданные при сборке сайта. Например, с использованием Contentlayer можно создавать поля на основе вычислений:

import { defineDocumentType, makeSource } from 'contentlayer/source-files';

export const Post = defineDocumentType(() => ({
  name: 'Post',
  filePathPattern: `**/*.mdx`,
  fields: {
    title: { type: 'json', required: true },
    author: { type: 'string', required: true },
    date: { type: 'date', required: true },
    tags: { type: 'list', of: { type: 'string' } },
  },
  computedFields: {
    slug: { type: 'string', resolve: (post) => post._raw.sourceFileName.replace('.mdx', '') },
    localizedTitle: {
      type: 'string',
      resolve: (post, { locale }) => post.title[locale] || post.title.en,
    },
  },
}));

export default makeSource({
  contentDirPath: 'posts',
  documentTypes: [Post],
});

computedFields позволяют создавать динамические свойства, такие как slug, переведённый заголовок, теги в нужном формате. Это освобождает от необходимости вручную управлять локализованными версиями в каждом MDX-файле.

Преобразование метаданных в компоненты

Метаданные можно использовать для создания динамических компонентов или оберток вокруг MDX-контента:

export function PostHeader({ metadata, locale }) {
  const title = metadata.title[locale] || metadata.title.en;
  const date = new Date(metadata.date).toLocaleDateString(locale);
  return (
    <header>
      <h1>{title}</h1>
      <p>{metadata.author} · {date}</p>
    </header>
  );
}

Это позволяет сохранять MDX чистым от логики локализации, при этом отображение полностью управляется на уровне React-компонентов.

Best Practices для переводов метаданных

  1. Хранение всех локалей в frontmatter — упрощает управление и поиск нужного текста.
  2. Использование computedFields для автоматических переводов и вычислений — предотвращает дублирование кода.
  3. Разделение метаданных и контента — frontmatter отвечает за структуру и данные, MDX — за содержимое и JSX.
  4. Стандартизация ключей локалейen, ru, de и т.д., чтобы обеспечить единообразную обработку.
  5. Проверка наличия перевода с fallback на английский или другой основной язык.

Практический пример

---
title:
  ru: "Учебник по MDX"
  en: "MDX Handbook"
author: "Мария Петрова"
date: "2026-03-23"
tags: ["MDX", "JS", "Frontend"]
---
import { PostHeader } from '../components/PostHeader';

<PostHeader metadata={frontmatter} locale="ru" />

# Введение

MDX объединяет возможности Markdown и JSX...

Использование frontmatter с переводами и компонентов React позволяет создавать полностью локализованные страницы, где контент, метаданные и оформление работают в единой связке без дублирования кода.

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