1

Little post if it can help some people...

We want to translate a sentence with 3 different links inside...

To do so, let's suppose we have a common.json file and inside we can find a sentence with multiple slot:

// /public/locales/en/common.json
{
    "multipleLink": {
        label: "This is a <1>link</1>, a <2>link2</2> and a <3>third</3>",
        "links": {
            "link": {
                "label": "first link",
                "url": "/url-first-link",
            }
            "link2": {
                "label": "second link",
                "url": "/url-second-link",
            }
            "third": {
                "label": "third link",
                "url": "/url-third-link",
            }
        }
    }
}

Not very beautiful but it work...

Then we can write some code:

import { ReactNode } from 'react';
import { Trans, useTranslation } from 'next-i18next';

// return "This is a first link, a second link and a third link"
const MyComponent = () => {
    return (
  <Trans i18nKey="multipleLink.label">
    <MyLinkComponent>_</MyLinkComponent>
    <MyLinkComponent>_</MyLinkComponent> // I found that trick to handle 9 slot 
    <MyLinkComponent>_</MyLinkComponent> // possible in the sentence if we want but
    <MyLinkComponent>_</MyLinkComponent> // it's very limited as you can see...
    <MyLinkComponent>_</MyLinkComponent>
    <MyLinkComponent>_</MyLinkComponent>
    <MyLinkComponent>_</MyLinkComponent> // I don't understand exactly what I did, and how,
    <MyLinkComponent>_</MyLinkComponent> // but it works... I'm still happy, if someone
    <MyLinkComponent>_</MyLinkComponent> // know the exact logic with those prompt I'm all ears
    <MyLinkComponent>_</MyLinkComponent>
  </Trans>
)}

/*
 * To handle how we will display our links and their action
 */
interface MyLinkComponentProps {
  children: ReactNode;
}
const MyLinkComponent = ({ children }: MyLinkComponentProps) => {
  const { t } = useTranslation();

  const handleClick: MouseEventHandler<HTMLButtonElement> = () => {
    console.log(children); // 'link' | 'link2' | 'third'
  };

  return (
    <a href={t(`multipleLink.links.${children}.url`)} onClick={handleClick}>
      {t(`multipleLink.links.${children}.label`)}
    </a>
  );
}

Because I didn't saw any solution to do that kind of thing, I wanted to share ✌️ BUT this is technically an ugly solution, if some want to complete, improve or even replace this solution I would be very grateful

Paul Bompard
  • 170
  • 1
  • 7

0 Answers0