Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I interpolate a Link component in Next-i18next / React i18next that changes position in the text

Currently I'm using Next.js with Next-i18next for I18N, but I understand that the React/i18next implementation is basically the same.

The problem I'm having is that I need to interpolate a next Link component inside some translation text, but depending on the language (English vs German), the order of the text and the link would change. For instance the text I'm struggling with is: 'Accept data policy' vs 'Datenschutzerklärung akzeptieren'

As of the moment I have a quick fix by creating two values in the translation JSON files for the text and the link and then swapping the position based on the current language. Obviously this is not a sustainable solution. I have tried to utilise the 'Trans' component but this is showing some unexpected behaviour where the translation only kicks in after the page is refreshed, otherwise you see the text inside the Trans component.

example:

 function LinkText({ href, children}) {
    return <Link to={href || ''}>{children}</Link>;
  }

  return (
      <Trans i18nKey="sentence">
         text before link
        <LinkText href="/data-policy">{t("dataPolicy")}</LinkText> 
         text after link
      </Trans>
  );

and the JSON in question:

{
  "sentence": "agree to our <1><0/></1>",
  "dataPolicy": "data policy"
}

Here's a link to CodeSandbox I made to replicate the problem with in React: link

(P.S The implementation of i18next doesn't seem to effectively swap out the languages in Codesandbox at the moment, but I included it as the code is there for a MWE)

Thanks in advance for your help, this has been driving me insane.

like image 720
HJEC Avatar asked Dec 30 '22 16:12

HJEC


1 Answers

You had few missing parts,

  1. Your i18next config was lack of a way to fetch the locale files, I've added i18next-http-backend.
  2. You should use Trans component to inject the link to the sentence. Your locale json should look like this:
{
  "sentence": "Accept <0>data policy</0>"
}
// TranslatedLink.js

import React from 'react';
import { useTranslation, Trans } from 'react-i18next';
import { Link } from 'react-router-dom';

function LinkText({ href, children }) {
  return <Link to={href || ''}>{children}</Link>;
}

export default function TranslatedLink() {
  const { t } = useTranslation(['common']);

  return (
    <div style={{ padding: 50 }}>
      <Trans i18nKey="sentence" t={t} components={[<LinkText href="/data-policy" />]} />
    </div>
  );
}

A working example: https://codesandbox.io/s/react-i18n-interpolation-issue-forked-ck8l4

like image 166
felixmosh Avatar answered Jan 05 '23 19:01

felixmosh