Can't read the multiple lang file in React Intl + TypeScript

2.1k Views Asked by At

I would like to use react intl to support multiple languages. I'm sure I have the file set up, but it doesn't load properly and doesn't show the text I have set up in yaml.

I'm getting an error message stating that loading is failing. What is wrong?

The error:

Error: [@formatjs/intl Error MISSING_TRANSLATION] Missing message: "Top.Title" for locale "en-US", using id as fallback.

index.tsx

import { IntlProvider } from 'react-intl'
import { chooseLocale } from './locales'

const lang = navigator.language

ReactDOM.render(
  <React.StrictMode>
    <IntlProvider locale={lang} messages={chooseLocale(lang)}>
      <App />
    </IntlProvider>
  </React.StrictMode>,
  document.getElementById('root'),
)

locales/index.ts

import yaml from 'js-yaml'

const en = yaml.load(`
Top:
  Title: Sample Title
  Message: Hello! { name }!
`)

const translationMessages = {
  en,
}

export const chooseLocale = (locale: string) => {
  console.log('Your locale :', locale)
  switch (locale) {
    case 'en-GB':
      return translationMessages.en
    default:
      return translationMessages.en
  }
}

hello.js

import { FormattedMessage } from 'react-intl'

<FormattedMessage id="Top.Title" />
1

There are 1 best solutions below

0
On

In React-intl, if you would like to keep your translation in an object format, i.e.

{ "Top":
  { "Title": "Sample Title" },
  { "Message": "Hello! { name }!" }
}

You should always flatten your keys and keep it into one level only:

{
  "Top.Title": "Sample Title",
  "Top.Message": "Hello! { name }!" }
}

To achieve this, you can make use of flatten library, which helps to auto flatten your object keys into one level only.

I have put your code into this sandbox and show how can you flatten your translation and resolve your problem: https://codesandbox.io/s/react-intl-64409927-zljmf

By the way you can use the hook "useIntl" provided by react-intl, which can access different method in react-intl easier (and keep your code cleaner/ readable).

 const intl = useIntl();
 return (<p>{intl.formatMessage({ id: "Top.Message" }, { name: "Apple" })}</p>)