MDX — это расширение Markdown, позволяющее встраивать JSX-компоненты прямо в текстовую разметку. В сочетании с современными фреймворками для Static Site Generation (SSG), такими как Next.js или Gatsby, MDX становится мощным инструментом для построения статических сайтов с динамическими компонентами.
Static Site Generation предполагает предкомпиляцию страниц на этапе
сборки проекта. При использовании MDX каждая .mdx-страница
сначала преобразуется в React-компонент, который затем рендерится в
HTML. Это обеспечивает:
Процесс выглядит следующим образом:
@next/mdx для
Next.js или gatsby-plugin-mdx для Gatsby).В Next.js это достигается через getStaticProps и getStaticPaths. Пример:
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { MDXRemote } from 'next-mdx-remote';
import { serialize } from 'next-mdx-remote/serialize';
const postsDirectory = path.join(process.cwd(), 'posts');
export async function getStaticPaths() {
const filenames = fs.readdirSync(postsDirectory);
const paths = filenames.map((name) => ({
params: { slug: name.replace(/\.mdx$/, '') },
}));
return { paths, fallback: false };
}
export async function getStaticProps({ params }) {
const fullPath = path.join(postsDirectory, `${params.slug}.mdx`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const { content, data } = matter(fileContents);
const mdxSource = await serialize(content, { scope: data });
return { props: { mdxSource, frontMatter: data } };
}
export default function Post({ mdxSource, frontMatter }) {
return (
{frontMatter.title}
);
}
Здесь:
fs и path читают локальные файлы MDX.gray-matter извлекает метаданные (frontMatter) из
MDX.next-mdx-remote сериализует MDX-контент в форму,
готовую для рендеринга React-компонентом.MDX позволяет импортировать и использовать React-компоненты прямо внутри Markdown. Для SSG это означает возможность включать интерактивные элементы без потери преимуществ статической генерации.
Пример:
// components/Alert.js
export default function Alert({ children, type }) {
return {children};
}
// pages/posts/[slug].js
import Alert from '../. ./components/Alert';
const components = { Alert };
;
В MDX-файле:
# Важное сообщение
Это предупреждение!
Статическая генерация преобразует это в HTML, а React-компонент
Alert подключается для интерактивности на клиенте, если
необходимо.
next/dynamic.Даже при статической генерации MDX поддерживает использование данных, полученных на этапе сборки:
export async function getStaticProps() {
const res = await fetch('https://api.example.com/posts');
const posts = await res.json();
const mdxSources = await Promise.all(
posts.map(async (post) => {
return {
slug: post.slug,
mdxSource: await serialize(post.content, { scope: post }),
};
})
);
return { props: { mdxSources } };
}
Таким образом, можно комбинировать преимущества статической генерации с актуальными данными, загруженными из API.