YouTube и Vimeo

MDX (Markdown for JSX) позволяет интегрировать JSX-компоненты непосредственно в Markdown-документы. Для работы с MDX в проекте на JavaScript необходимо установить несколько ключевых пакетов: @mdx-js/react и @mdx-js/loader (для проектов на Webpack) или @mdx-js/mdx (для сборки на Node.js). Конфигурация сборки зависит от используемой платформы, но в любом случае главный принцип — MDX-файлы обрабатываются как обычные JSX-компоненты, что позволяет использовать React-компоненты внутри Markdown.

npm install @mdx-js/react @mdx-js/loader

Для интеграции с Webpack нужно добавить правило:

module: {
  rules: [
    {
      test: /\.mdx?$/,
      use: [
        'babel-loader',
        '@mdx-js/loader'
      ]
    }
  ]
}

После этого MDX-файлы можно импортировать в проект как обычные компоненты:

import Content from './content.mdx';

function App() {
  return <Content />;
}

Встраивание видео с YouTube и Vimeo

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

Компонент для YouTube

import React from 'react';

export const YouTube = ({ id, width = 560, height = 315 }) => (
  <iframe
    width={width}
    height={height}
    src={`https://www.youtube.com/embed/${id}`}
    title="YouTube video player"
    frameBorder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowFullScreen
  />
);
  • id — идентификатор видео на YouTube.
  • width и height — размеры плеера (по умолчанию 560x315, но можно переопределять).
  • Использование allowFullScreen гарантирует возможность просмотра в полноэкранном режиме.

Компонент для Vimeo

import React from 'react';

export const Vimeo = ({ id, width = 640, height = 360 }) => (
  <iframe
    src={`https://player.vimeo.com/video/${id}`}
    width={width}
    height={height}
    frameBorder="0"
    allow="autoplay; fullscreen; picture-in-picture"
    allowFullScreen
    title="Vimeo video player"
  />
);
  • Параметры id, width и height аналогичны компоненту для YouTube.
  • Vimeo поддерживает автопроигрывание и полноэкранный режим.

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

MDX позволяет зарегистрировать свои компоненты, чтобы их можно было использовать прямо в Markdown. Это достигается через контекст MDXProvider.

import { MDXProvider } from '@mdx-js/react';
import { YouTube, Vimeo } from './VideoComponents';
import Content from './content.mdx';

const components = { YouTube, Vimeo };

function App() {
  return (
    <MDXProvider components={components}>
      <Content />
    </MDXProvider>
  );
}

Теперь внутри content.mdx можно вставлять видео так:

# Пример видео

<YouTube id="dQw4w9WgXcQ" width={800} height={450} />

<Vimeo id="76979871" width={800} height={450} />

Дополнительные возможности

  • Адаптивные видео: с помощью CSS можно сделать плееры полностью адаптивными, используя position: relative для контейнера и padding-top с пропорцией видео.
.video-wrapper {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 16:9 */
}

.video-wrapper iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
<div className="video-wrapper">
  <YouTube id="dQw4w9WgXcQ" />
</div>
  • Передача параметров: YouTube и Vimeo поддерживают query-параметры, например autoplay, loop, start, end, muted. Их можно передавать через объект options и формировать строку запроса динамически.
  • Композиция с другими компонентами: MDX позволяет оборачивать видео в модальные окна, карточки, слайдеры или любые кастомные компоненты, сохраняя чистоту Markdown.

Работа с типизацией

Для TypeScript удобно определить интерфейсы пропсов:

interface VideoProps {
  id: string;
  width?: number;
  height?: number;
  autoplay?: boolean;
}

export const YouTube: React.FC<VideoProps> = ({ id, width = 560, height = 315, autoplay = false }) => {
  const params = new URLSearchParams();
  if (autoplay) params.set('autoplay', '1');

  return (
    <iframe
      width={width}
      height={height}
      src={`https://www.youtube.com/embed/${id}?${params.toString()}`}
      title="YouTube video player"
      frameBorder="0"
      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
      allowFullScreen
    />
  );
};
  • Типизация помогает избежать ошибок при передаче необязательных параметров.
  • Позволяет безопасно расширять функционал (например, добавлять captions или темы оформления).

Совместимость и производительность

  • MDX полностью совместим с React 17+ и React 18.
  • Использование iframe не влияет на SSR (Server-Side Rendering), так как плеер загружается только на клиенте.
  • Для оптимизации загрузки видео можно использовать ленивую загрузку (loading="lazy") в iframe:
<iframe
  loading="lazy"
  width={width}
  height={height}
  src={`https://www.youtube.com/embed/${id}`}
  frameBorder="0"
  allowFullScreen
/>

Это уменьшает нагрузку на страницу при множестве видео.


Интеграция с CMS

MDX часто используется совместно с системами управления контентом (CMS), такими как Contentful, Sanity или Strapi. Видео-компоненты подключаются к CMS через поля типа rich-text или MDX content, что позволяет редактировать Markdown с видео прямо через интерфейс редактора. Это делает публикацию и обновление видео-контента максимально гибкой и независимой от фронтенд-разработки.