Server-side rendering (SSR) позволяет генерировать HTML на сервере до того, как страница будет отправлена клиенту. В контексте MDX это особенно полезно, так как позволяет сразу отдавать готовый контент с JSX-компонентами, встроенными прямо в текст, без необходимости ждать выполнения на стороне клиента.
MDX — это расширение Markdown, которое позволяет использовать JSX внутри Markdown-документов. Это открывает возможности динамического контента в статичных статьях и документации, сохраняя при этом читаемость исходного Markdown.
Для работы с MDX на сервере чаще всего используют такие инструменты,
как @mdx-js/mdx и @mdx-js/react. Основной
процесс включает три шага:
Компиляция MDX в JSX MDX-файлы сначала
преобразуются в JSX-код с помощью функции compile или
compileSync из @mdx-js/mdx. Например:
import { compile } from '@mdx-js/mdx';
import fs from 'fs';
const source = fs.readFileSync('example.mdx', 'utf8');
const compiled = await compile(source, { outputFormat: 'function-body' });
Здесь ключевой момент — outputFormat: 'function-body',
который возвращает функцию для рендеринга контента на сервере.
Создание компонента для рендеринга После
компиляции необходимо превратить скомпилированный код в React-компонент.
Для этого используют @mdx-js/react и функцию
MDXContent:
import { MDXProvider } from '@mdx-js/react';
import * as runtime from 'react/jsx-runtime';
const MDXComponent = new Function('React', `${compiled.value}`)(runtime);
MDXProvider позволяет обернуть MDX-контент, предоставляя
кастомные компоненты для рендеринга заголовков, ссылок, изображений и
других элементов.
Рендеринг на сервере Для SSR используют
react-dom/server:
import ReactDOMServer from 'react-dom/server';
const html = ReactDOMServer.renderToString(
<MDXProvider components={customComponents}>
<MDXComponent />
</MDXProvider>
);
Полученный HTML можно сразу вставлять в шаблон страницы или отдавать как ответ на HTTP-запрос.
Кэширование скомпилированного MDX Компиляция MDX в JSX — процесс затратный по времени. Для ускорения серверной генерации рекомендуется сохранять скомпилированные файлы в кэш или использовать систему сборки на этапе деплоя.
Разделение компонентов и контента В MDX можно выносить часто используемые элементы в отдельные React-компоненты. Это снижает дублирование кода и ускоряет SSR, так как повторно используемые компоненты уже загружены в память сервера.
Lazy-loading для тяжелых компонентов Если MDX содержит интерактивные элементы, их рендеринг на клиенте можно делать через динамический импорт. На сервере оставляется базовый HTML, а интерактивность подключается позже.
Next.js Next.js имеет встроенную поддержку SSR.
MDX интегрируется через @next/mdx или
next-mdx-remote. Пример:
import { serialize } from 'next-mdx-remote/serialize';
import { MDXRemote } from 'next-mdx-remote';
export async function getServerSideProps() {
const source = fs.readFileSync('example.mdx', 'utf8');
const mdxSource = await serialize(source);
return { props: { mdxSource } };
}
export default function Page({ mdxSource }) {
return <MDXRemote {...mdxSource} components={customComponents} />;
}
Здесь MDX компилируется на сервере и передается в компонент
MDXRemote для рендеринга на клиенте.
Express + React Можно использовать Express для
отдачи HTML, сгенерированного с помощью react-dom/server.
Важное отличие от Next.js — ручное управление компиляцией и кэшированием
MDX.
Состояние компонентов React-компоненты в MDX
могут иметь состояние. При SSR состояние создается на сервере, но на
клиенте оно пересоздается заново, что может вызвать рассинхронизацию.
Использование useEffect для инициализации состояния после
монтирования решает проблему.
Глобальные стили Стили компонентов, встроенных в MDX, должны быть корректно подключены на сервере. Иначе на клиенте будет «мигание» контента без стилей.
Асинхронные операции SSR не поддерживает асинхронные хуки напрямую в компоненте MDX. Необходимо предварительно получать данные и передавать их через props.
MDXProvider для унификации
отображения элементов.Эта схема позволяет полностью использовать возможности MDX в серверной среде, сочетая гибкость JSX с производительностью SSR и стабильной выдачей готового HTML.