Dev Highlights

Доки по разработке

This project is maintained by teniryte

6. MDX и кастомные компоненты

Ваш модуль 20-mdx показывает, как в Next.js:

6.1. Базовая интеграция MDX: страница с импортом .mdx

В Next.js MDX‑страницы можно использовать как обычные React‑компоненты:

Пример страницы app/20-mdx/page.tsx:

// @ts-nocheck

import Welcome from '@/markdown/welcome.mdx';

function CustomH1({ children }) {
  return <h1 style={{ color: 'blue', fontSize: '100px' }}>{children}</h1>;
}

const overrideComponents = {
  h1: CustomH1,
};

export default function Page() {
  return <Welcome components={overrideComponents} />;
}

Принципы:

6.2. Общий layout для MDX‑страниц

Файл app/20-mdx/layout.tsx задаёт:

Пример:

// @ts-nocheck

export default function MdxLayout({ children }: { children: React.ReactNode }) {
  // Общие стили/оформление для всех MDX‑страниц в этом маршруте
  return <div style={{ color: 'blue' }}>{children}</div>;
}

Принципы:

6.3. useMDXComponents: глобовое переопределение элементов

Файл src/mdx-components.tsx предоставляет функцию useMDXComponents:

Пример:

import type { MDXComponents } from 'mdx/types';
import Image, { ImageProps } from 'next/image';

export function useMDXComponents(components: MDXComponents): MDXComponents {
  return {
    // Кастомный <h1> для всего MDX
    h1: ({ children }) => (
      <h1 style={{ color: 'red', fontSize: '48px' }}>{children}</h1>
    ),

    // Кастомный <img>, обёрнутый в next/image
    img: (props) => (
      <Image
        sizes="100vw"
        style={{ width: '100%', height: 'auto' }}
        {...(props as ImageProps)}
      />
    ),

    // Не забываем прокинуть переданные компоненты
    ...components,
  };
}

Принципы:

6.4. Пример MDX‑файла с использованием кастомных компонентов

Предположим, у вас есть файл markdown/welcome.mdx:

# Добро пожаловать в документацию

Это пример MDX‑страницы, где:

- мы можем использовать **Markdown** синтаксис;
- вставлять React‑компоненты прямо внутрь;
- использовать кастомные компоненты для `h1`, `img` и других тегов.

![Картинка](./image.png)

<CustomButton>Нажми меня</CustomButton>

При рендере:

6.5. Паттерн для документации на MDX

Ваш модуль 20-mdx отлично подходит как основа для собственной документации:

src/
  markdown/
    intro.mdx
    getting-started.mdx
    forms.mdx
    isr.mdx
app/
  docs/
    layout.tsx        // общий layout для документации
    page.tsx          // список разделов/оглавление
    [slug]/
      page.tsx        // рендер определённого MDX по slug

Пример рендера раздела документации по slug:

// app/docs/[slug]/page.tsx
import Intro from '@/markdown/intro.mdx';
import Forms from '@/markdown/forms.mdx';

const map = {
  intro: Intro,
  forms: Forms,
} as const;

export default function DocsPage({ params }: { params: { slug: string } }) {
  const MDX = map[params.slug as keyof typeof map] ?? Intro;
  return <MDX />;
}

6.6. Общие принципы работы с MDX в Next.js

С учётом ваших примеров:

Этот модуль‑конспект поможет быстро вспомнить, как устроена связка Next.js + MDX в вашем проекте и как расширять её под свою документацию или блог.