I'm trying to implement a language switch using react-i18next in a React TS app. firstly i added text manually in english and created a TextHighlight component looking like this:
import React from "react";
type Props = {
children: React.ReactNode;
};
export default function TextHighlight({ children }: Props) {
return <span className="text-[var(--primary)] font-bold"> {children}</span>;
}
In my translation JSON file, I have this text:
"text1": "<highlight>Lorem ipsum</highlight> dolor sit amet, consectetur adipiscing elit.
Nulla tincidunt mi ultrices metus imperdiet mollis.
Nam sit amet tortor a felis <highlight>finibus dictum</highlight>.
Suspendisse potenti. Vivamus sed tortor suscipit, tincidunt sapien in, finibus nunc.
Curabitur egestas aliquam scelerisque. Vivamus faucibus massa et <highlight>lacus egestas</highlight>,
a commodo tortor aliquam. Mauris id euismod augue, nec euismod turpis."
I want to render this using the <Trans> component so that <highlight> tags are replaced with my custom TextHighlight component. However, since my TextHighlight uses children, I'm not sure how to make this work correctly.
Have you ever dealt with replacing custom tags like <highlight> in react-i18next using a component like TextHighlight that takes children? Is it possible to solve this with <Trans>, and if not, what’s the best alternative way to achieve this kind of inline formatting in translations?
tried:
<Trans
i18nKey="introText"
components={{
highlight: <TextHighlight />
}}
/>
<Trans
i18nKey="introText"
components={{
highlight: TextHighlight
}}
/>
<Trans
i18nKey="introText"
components={{
highlight: <TextHighlight /> as unknown as React.ReactElement
}}
/>
<Trans
i18nKey="text1"
components={{
highlight: (children: string) => (
<TextHighlight>{children}</TextHighlight>
),
}}
/>
use custom component similar to span to highlight some wirds in text
resulted in errors with childrens
Well, I came up with this solution:
<p>
{t("text1")
.split(/(<highlight>.*?<\/highlight>)/g)
.map((part, index) => {
const match = part.match(/<highlight>(.*?)<\/highlight>/);
if (match) {
return <TextHighlight key={index}>{match[1]}</TextHighlight>;
}
return <React.Fragment key={index}>{part}</React.Fragment>;
})}
</p>