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 позволяет использовать динамический импорт для загрузки нужного файла контента. Сочетая это с контекстом языка, можно подгружать страницу на нужном языке:
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;
Ключевые моменты:
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 позволяет регистрировать глобальные компоненты через
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>
);
Преимущества подхода:
Для более сложных сценариев мультиязычности рекомендуется
использовать библиотеки, такие как react-intl или
i18next, совместно с MDX. Пример интеграции с
i18next:
import { useTranslation } from 'react-i18next';
const TranslatedMDX = ({ page }) => {
const { t } = useTranslation();
// t('key') можно использовать в MDX-компонентах через пропсы
};
Возможности:
MDXProvider обеспечивает консистентность
компонентов.Этот подход позволяет создать полностью мультиязычный сайт на основе MDX с минимальной дубликацией кода и легким управлением контентом.