Support for Trans Component
leandro-silva-me opened this issue · 4 comments
Trans component from i18next allows listing the custom component.
This would be really useful and facilitate migrating from next-translate
or react-i18next
to next-export-i18n
.
Example:
<Trans
i18nKey="description"
components={{
privacyPolicyLink: (
<PrivacyLink lang={lang} type={'privacy-policy'} />
),
generalTermsLink: (
<PrivacyLink lang={lang} type={'general-terms'} />
),
cookiePolicyLink: (
<PrivacyLink lang={lang} type={'cookie-policy'} />
)
}}
/>
Hi leandro-silva-me,
thank you for taking the time to contribute.
From the documentation:
While gives you a lot of power by letting you interpolate or translate complex React elements, the truth is: in most cases you don't even need it.
As long you have no React/HTML nodes integrated into a cohesive sentence (text formatting like strong, em, link components, maybe others), you won't need it - most of the times you will be using the good old t function.
next-export-i18n
supports the translation of strings with HTML nodes through Moustache templates.
The Trans component is fairly complex, it is about ~335 lines of code and another ~1000 lines of tests.
Unfortunately, recreating this functionality is out scope for me. If you want to fork and contribute this functionality to next-export-i18n
I will happily support you.
I don't know your exact use case, but maybe combining the t()
function with Moustache templates could be something you can leverage?
Cheers,
Martin
Unfortunately, in my case, I won't be able to use Moustache templates since they won't work for React Elements. However, I will try to fork the Trans on this project. Thanks!
Did you start to look into this? I'm trying to see if this library can replace next-i18next for us and enable building via next export
@razzeee not yet. I made a custom component on my project that gets w/e inside a mustache template and replaces it with a React Element.
Example:
translations.json
{
"textExample": "This Text should have custom elements {{custom1}} and {{custom2}}."
"custom1": "here",
"custom2": "also here",
}
CustomComponent.ts
const renderText = (text: string) => {
const { t } = useTranslation();
const parts: (string | Element)[] = text.split(/{{\s*[\w\.]+\s*}}/g);
let cont = 0;
for (let i = 1; i < parts.length; i += 2) {
const matches = text.match(/{{\s*[\w\.]+\s*}}/g);
if (matches) {
const textMatch = matches[cont];
if (textMatch) {
const mustacheMatch = textMatch.match(/[\w\.]+/);
if (mustacheMatch) {
const innerText = mustacheMatch[0];
parts.splice(
i,
0,
(<MyComponent type={innerText}>{t(innerText)}</MyComponent >) as any
);
}
}
}
cont++;
}
return parts;
};
const CustomComponent: React.FC = () => {
const { t } = useTranslation();
const newText = renderText(t('textExample'));
return <>{newText}</>;
};
This solution is temporary but works for what I need for now.