Search code examples
i18nextreact-i18next

i18next bold and list formatter together in react


I have an array const attributes = ['First name', 'Second name', 'Date']

and I want to render the text Sorry coudn't save "First name", "Second Name" and "Date".

As you can see I want to first make each item bold and wrapped with quotes and then use the Intl.ListFormat

Im a bit lost on how to do that and could use a little help.

This is what I have

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    debug: true,

    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
      format: function (value, format, lng) {
        if (format === "list") {
          value = value.map((v) => `<bold>${v}</bold>`);
          return new Intl.ListFormat(lng, {
            style: "long",
            type: "conjunction"
          }).format(value);
        }
      }
    },
    resources: {
      en: {
        translation: {
          attr: "A list of {{attr, list}}"
        }
      }
    }
  });
<Trans
 i18nKey="attr"
 values={{ attr }}
 components={{ bold: <b /> }}
 shouldUnescape={true}
/>
A list of <bold>First name</bold>, <bold>Second name</bold> and <bold>DOB</bold>

Solution

  • You are mixing interpolation and Trans component. This is not possible.

    Option 1: use t function

    t('attr', { attr })
    

    Option 2: Trans without list formatting

    // resources:
    attr: "A list of <1>{{firstName}}</1>, <3>{{lastName}}</3> and <5>{{extra}}</5>"
    
    // Trans:
    <Trans
      i18nKey="attr"
      values={{ firstName: attr[0], lastName: attr[1], extra: attr[2] }}
    >A list of <b>{attr[0]}</b>, <b>{attr[1]}</b> and <b>{attr[2]}</b></Trans>