I am using i18next with React for my project. For most of the translations I use the t() function with normal text. However, for some cases I would prefer to use the <Trans /> component.
I prepared some example below:
function Example() {
const { t } = useTranslation();
const reusableComponent = <p>{t('TranslateMeOnlyOnce')}</p>;
return (
<>
{reusableComponent}
<Trans i18nKey={'OnlyOnceWrapper'}>
The reusable component says {reusableComponent}
</Trans>
</>
)
}
Which expect would my ranslation file to look something like this:
...
TranslateMeOnlyOnce: 'Translate me only once',
OnlyOnceWrapper: 'The reusable component says <1>Translate me only once</1>',
...
However, as you can see I would be required to translate the text of the nested component twice. I would really like to just translate the The reusable component says {reusableComponent} in the second translation string and not all of the first translation string for another time.
For those wondering why I would want to do this, lets say const reusableComponent is a Create Button with some function to create a new entry placed at the top of the Screen. When however, there is no entry displayed in my list of entries I want to display a message saying something like: ‘Unfortunately there is no entry yet. Click on [CreateButtonIsDisplayedHere] to create a new entry’.
Let’s say I experience that users find a translation ‘New’ instead of ‘Create’ more useful or the other way round, I would want to change only the translation of the button and not every other place containing this button.
I also found myself a solution to this issue already, however, in my experience this is super ugly to maintain as I need to pass the content as string and not as React child Element which pretty much take all advantages of using the <Trans /> Component and I could better use the t() function using sprintf.
function UglySolution() {
const { t } = useTranslation();
const reusableComponent = <p>{t('Translate me only Once')}</p>;
return (
<>
{reusableComponent}
<Trans
i18nKey={'OnlyOnceWrapper'}
components={[reusableComponent]}
variables={{ v: t('Translate me only Once') }}
defaults='The reusable component says <1>{{v}}</1>'
/>
</>
)
}
Which would expect my translation file to look something like this:
...
TranslateMeOnlyOnce: 'Translate me only once',
OnlyOnceWrapper: 'The reusable component says <1>{{v}}</1>',
...
So my question is: Can I make my translation to look something like the second example I created without using the ugly <Trans /> code from the second example and more something like in the first example I created?