reactjsreact-i18next

How can I translate dynamic comma-seperated lists with react-18next?


I have a dynamic comma-seperated list of links with the word "and" instead of a comma at last.

So my List can have these four states:

  1. "You can use A."
  2. "You can use A and B."
  3. "You can use A, B and C."
  4. "You can use A, B, C and D."

The dynamic list is rendered in React and now I want to translate it with react-18next and the Transcomponent. But I don't get it.

It should translate the text before the list and the word "and". A, B, C and D are names, which are the same in every language.

<Trans>
    <span>
        You can use <>{useLinkList}</>.
    </span>
</Trans>

The i18n looks like this in the third case (because of React Fragments):

"<0><0><1>You can use <1><0>A</0><1>, </1><2>B</2><3> and </3><4>C</4></1>.</1></0></0>"

But how can I get it work with all 4 cases?


Solution

  • There is a programmatic solution for your problem, which could lead to some translation/internationalization problems later in the project. These could be:

    Split the useLinkList in two parts. The first contains a list with ["A"] upto ["A", "B", "C"]. The second part contains only the last Element or is omited. Call the translation function twice to translate "and" as well.

    // In your component
    {t("linkList", {
            elements: [[FirstPart].join(","), lastElement].join(t(" and ")),
    })}
    
    // In your locale
    {
    "linkList": "You can use {{ elements }}.",
    " and ": " and "
    }
    
    

    A different approach which is more flexible for localization would be to use ICU Messages. If the cases are fixed, an option could be to use a select statement. Here is a quick guide for the syntax.