Переключение языков

MDX (Markdown + JSX) представляет собой расширение Markdown, которое позволяет использовать компоненты React внутри Markdown-документов. Эта гибкость открывает возможности для динамического контента, включая поддержку мультиязычности. Для реализации переключения языков в MDX потребуется сочетание нескольких подходов: использование контекста React, динамического импорта контента и специализированных библиотек локализации.


Организация структуры контента для нескольких языков

Для поддержки мультиязычного контента часто используют отдельные файлы MDX для каждого языка. Например, для страницы about создаются файлы:

/content/about.en.mdx
/content/about.ru.mdx

Каждый файл содержит текст на соответствующем языке, а JSX-компоненты остаются идентичными между версиями. Такой подход обеспечивает:

  • Простоту управления контентом.
  • Легкость добавления новых языков.
  • Возможность динамического импорта контента на основе выбранного языка.

Создание контекста для текущего языка

Использование React Context позволяет хранить состояние текущего языка и предоставлять его всем компонентам в дереве приложения. Пример реализации:

import { createContext, useContext, useState } from 'react';

const LanguageContext = createContext();

export const LanguageProvider = ({ children }) => {
  const [language, setLanguage] = useState('en');

  const switchLanguage = (lang) => {
    setLanguage(lang);
  };

  return (
    <LanguageContext.Provider value={{ language, switchLanguage }}>
      {children}
    </LanguageContext.Provider>
  );
};

export const useLanguage = () => useContext(LanguageContext);

Пояснение:

  • language хранит текущий язык.
  • switchLanguage позволяет менять язык на лету.
  • useLanguage — удобный хук для доступа к контексту внутри компонентов.

Динамический импорт MDX по языку

MDX позволяет использовать динамический импорт для загрузки нужного файла контента. Сочетая это с контекстом языка, можно подгружать страницу на нужном языке:

import { useEffect, useState } from 'react';
import { useLanguage } from './LanguageContext';

const MDXPage = ({ page }) => {
  const { language } = useLanguage();
  const [Content, setContent] = useState(null);

  useEffect(() => {
    const loadContent = async () => {
      const module = await import(`../content/${page}.${language}.mdx`);
      setContent(() => module.default);
    };

    loadContent();
  }, [language, page]);

  if (!Content) return <p>Загрузка...</p>;
  return <Content />;
};

export default MDXPage;

Ключевые моменты:

  • Путь к MDX-файлу формируется динамически по выбранному языку.
  • Контент обновляется автоматически при смене языка.
  • Компонент Content рендерится как обычный React-компонент.

Интеграция кнопок переключения языков

Для удобства пользователя создаются кнопки или меню, которые вызывают метод switchLanguage:

import { useLanguage } from './LanguageContext';

const LanguageSwitcher = () => {
  const { language, switchLanguage } = useLanguage();

  return (
    <div>
      <button disabled={language === 'en'} onCl ick={() => switchLanguage('en')}>
        English
      </button>
      <button disabled={language === 'ru'} onCl ick={() => switchLanguage('ru')}>
        Русский
      </button>
    </div>
  );
};

export default LanguageSwitcher;

Особенности:

  • Кнопки блокируются, если выбран текущий язык.
  • Смена языка мгновенно обновляет все компоненты, использующие useLanguage.

Поддержка глобальных компонентов в MDX

MDX позволяет регистрировать глобальные компоненты через MDXProvider. Это особенно важно при мультиязычном контенте, если внутри MDX используются общие элементы:

import { MDXProvider } from '@mdx-js/react';
import CustomHeading from './CustomHeading';

const components = {
  h1: CustomHeading,
  // можно переопределять другие элементы Markdown
};

const App = () => (
  <MDXProvider components={components}>
    <LanguageProvider>
      <LanguageSwitcher />
      <MDXPage page="about" />
    </LanguageProvider>
  </MDXProvider>
);

Преимущества подхода:

  • Глобальные стили и компоненты одинаковы для всех языков.
  • MDX-файлы остаются чистыми, без повторного объявления общих компонентов.
  • Позволяет централизованно управлять визуальным стилем контента.

Использование библиотек локализации

Для более сложных сценариев мультиязычности рекомендуется использовать библиотеки, такие как react-intl или i18next, совместно с MDX. Пример интеграции с i18next:

import { useTranslation } from 'react-i18next';

const TranslatedMDX = ({ page }) => {
  const { t } = useTranslation();
  // t('key') можно использовать в MDX-компонентах через пропсы
};

Возможности:

  • Поддержка плейсхолдеров и параметров в текстах.
  • Автоматическое переключение языков.
  • Работа с сложными форматами дат, чисел и валют.

Резюме по реализации переключения языков в MDX

  • MDX-файлы организуются по языкам.
  • React Context хранит состояние текущего языка.
  • Динамический импорт загружает нужный MDX-файл.
  • Кнопки и элементы UI вызывают смену языка через контекст.
  • MDXProvider обеспечивает консистентность компонентов.
  • Для сложной локализации интегрируются специализированные библиотеки.

Этот подход позволяет создать полностью мультиязычный сайт на основе MDX с минимальной дубликацией кода и легким управлением контентом.