Мы используем пакет MDXJS для записи контента в Markdown и используем в нем компоненты React.
Есть ли способ использовать пакет i18next / реагировать-i18next внутри файлов MDX / Markdown?





i18next внутри MDX:Когда вы импортируете файл MDX, вы просто используете его как любой другой компонент React:
import { default as SomeContent } from './some-content.mdx';
...
<SomeContent />
Следовательно, вы также можете передать некоторые свойства, в данном случае функцию t, и использовать их внутри определенными способами:
import { default as SomeContent } from './some-content.mdx';
export const SomeComponent: React.FC = React.memo((props) => {
const { t } = useTranslation();
return (
<SomeContent t = { t } someProp = "Some value" />
);
});
Если вы хотите проверить, работает ли это, или посмотреть, какие реквизиты доступны из вашего файла MDX, добавьте в него следующее:
<pre>{ JSON.stringify(props, null, ' ') }</pre>
<pre>{ typeof props.t }</pre>
В приведенном выше примере будет отображаться:
{"someProp":"Some value"}
function
Обратите внимание, что вы не можете использовать эти свойства внутри «сырых» элементов MD, даже если вы добавите вокруг них оболочку:
### Doesn't work: { props.t('some.translation') }
Doesn't work: { props.t('some.translation') }.
Doesn't work: <>{ props.t('some.translation') }</>.
Doesn't work: <Fragment>{ props.t('some.translation') }</Fragment>.
Doesn't work: <span>{ props.t('some.translation') }</span>.
Поэтому вам придется вместо этого писать теги HTML:
<h3>Works: { props.t('some.translation') }</h3>
<p>Works: { props.t('some.translation') }.</p>
<p>Works: <>{ props.t('some.translation') }</>.</p>
<p>Works: <Fragment>{ props.t('some.translation') }</Fragment>.</p>
<p>Works: <span>{ props.t('some.translation') }</span>.</p>
MDX в i18next:Если вы установите returnObjects: true в своей конфигурации i18next, вы также можете добавить компоненты MDX в свои файлы перевода:
import { default as ContentEN } from './content.en.mdx';
import { default as ContentES } from './content.es.mdx';
i18next.use(initReactI18next).init({
resources: {
en: {
translation: {
content: ContentEN,
},
},
es: {
translation: {
content: ContentES,
},
},
},
returnObjects: true,
}));
И затем вы могли бы использовать его таким образом в любом из ваших компонентов (и да, вы также можете передать t или любую другую опору, как и раньше:
export const SomeComponent: React.FC = React.memo((props) => {
const { t } = useTranslation();
const Content = t('content');
return (
<Content t = { t } someProp = "Some value" />
);
});
i18next внутри @mdx-js/runtime:Если вы используете @mdx-js/runtime, вы должны передать свои реквизиты как scope:
import { default as SomeContent } from './some-content.mdx';
export const SomeComponent: React.FC = React.memo((props) => {
const { t } = useTranslation();
return (
<MDX components = { ... } scope = { { t, someProp: 'Some value' } }>{ props.mdx }</MDX>
);
});
Вы имеете в виду что-то подобное? npmjs.com/package/i18next-markdown-jsx-plugin