Основы MDX синтаксиса

Что такое MDX

MDX (Markdown + JSX) — это расширение синтаксиса Markdown, которое позволяет интегрировать JSX-компоненты прямо в текстовую разметку. В отличие от обычного Markdown, MDX превращает документ в полноценный модуль JavaScript, предоставляя возможность использовать компоненты, пропсы и динамическое поведение прямо внутри Markdown-файлов.

Ключевая особенность MDX заключается в том, что документ больше не является просто текстом — это полноценный JavaScript-модуль, который можно импортировать и рендерить.


Основные элементы синтаксиса

1. Markdown-синтаксис

MDX полностью сохраняет возможности стандартного Markdown:

  • Заголовки:

    # Заголовок 1 уровня
    ## Заголовок 2 уровня
  • Списки:

    - Пункт списка
    - Еще один пункт
  • Ссылки и изображения:

    [Текст ссылки](https://example.com)
    ![Описание изображения](image.png)
  • Форматирование текста:

    **жирный текст**, *курсив*, `код`
2. Встраивание JSX

В MDX можно вставлять JSX-компоненты с использованием обычного синтаксиса React:

<MyButton color="blue">Нажми меня</MyButton>

Любой импортируемый или объявленный компонент можно использовать так же, как и в React. Важно, что JSX внутри MDX должен быть корректным с точки зрения JavaScript — теги должны быть закрыты, а атрибуты валидны.

3. Импорты и экспорты

MDX поддерживает стандартные механизмы ES Modules:

import { MyComponent } from './components/MyComponent';

export const meta = {
  title: 'Пример документа'
};

Импортированные компоненты можно использовать прямо в документе, а экспортированные объекты позволяют хранить метаданные или конфигурацию документа.


Взаимодействие с Rehype и Remark

MDX тесно интегрируется с экосистемой Remark и Rehype для парсинга и трансформации Markdown и HTML.

  • Remark — используется для работы с AST (abstract syntax tree) Markdown. С его помощью можно создавать плагины, обрабатывать текст, добавлять или модифицировать элементы Markdown перед рендерингом.
  • Rehype — аналогично, но работает с HTML-структурой. После того как Markdown преобразован в HTML, Rehype позволяет изменять дерево HTML, добавлять атрибуты, фильтровать теги и т.д.

Пример подключения плагина Remark для подсветки синтаксиса кода:

import remarkGfm from 'remark-gfm';
import { compile } from '@mdx-js/mdx';

const mdxSource = `
\`\`\`js
console.log("Hello MDX")
\`\`\`
`;

const result = await compile(mdxSource, {
  remarkPlugins: [remarkGfm]
});

Здесь remarkGfm добавляет поддержку расширенного синтаксиса Markdown, включая таблицы и автолинк.


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

Компоненты можно как импортировать, так и объявлять прямо внутри документа:

export const Alert = ({ children }) => (
  <div style={{ border: '1px solid red', padding: '10px' }}>
    {children}
  </div>
);

<Alert>Важное сообщение!</Alert>

MDX позволяет использовать пропсы, условные конструкции и JavaScript-выражения:

{[1, 2, 3].map(n => <p key={n}>Пункт {n}</p>)}

Разделение логики и разметки

MDX позволяет сохранять чистую архитектуру, отделяя визуальные компоненты от контента:

  • Контент — основной текст и разметка Markdown.
  • Презентация — React-компоненты, отвечающие за визуализацию.
  • Метаданные — экспортируемые объекты с информацией о документе (title, date, tags).

Пример структурирования MDX-документа:

export const meta = {
  title: 'Документ с компонентами',
  date: '2026-03-22'
};

import { Note } from './components/Note';

# Заголовок документа

Это обычный Markdown-текст.

<Note>Важная заметка прямо в тексте</Note>

Особенности синтаксиса

  1. Комментарии в MDX можно писать как в Markdown, так и в JSX:
<!-- Это Markdown-комментарий -->

{/* Это JSX-комментарий */}
  1. Inline JSX можно вставлять в любой части текста, но нужно учитывать ограничения JSX:
Текст с <strong>выделением</strong> прямо внутри строки.
  1. Атрибуты компонентов могут быть выражениями Jav * aScript:
<MyButton color={isActive ? 'green' : 'gray'}>Нажми</MyButton>
  1. Блоки кода поддерживают синтаксис с указанием языка, что упрощает интеграцию с плагинами для подсветки:
```python
def hello():
    print("Hello MDX")

---

#### Работа с AST

Remark и Rehype превращают MDX-документ в дерево абстрактного синтаксиса:

- **Remark AST** — структура Markdown-тегов (`heading`, `paragraph`, `list`).
- **Rehype AST** — HTML-дерево после трансформации Markdown.

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

```javascript
import rehypeSlug from 'rehype-slug';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';

const result = await compile(mdxSource, {
  rehypePlugins: [rehypeSlug, rehypeAutolinkHeadings]
});

Здесь rehypeSlug добавляет id к каждому заголовку, а rehypeAutolinkHeadings делает их кликабельными.


Практические советы по синтаксису

  • JSX-теги в тексте должны быть корректно закрыты (<MyComp /> вместо <MyComp>), иначе сборка MDX завершится ошибкой.
  • Пробелы и отступы важны, особенно при использовании вложенных компонентов.
  • Комбинирование Markdown и JSX требует внимательного форматирования, чтобы не нарушить AST.

MDX синтаксис предоставляет мощные возможности: от простого форматирования Markdown до полноценного использования React-компонентов и динамических данных внутри документа. Правильное понимание структуры AST и взаимодействия с Remark/Rehype открывает путь к созданию гибких, интерактивных документов и учебных материалов.