28

I'm trying to use react-intl package inside an app. The app is rendered on the server so I wrote some code to determine which language to use and serve into IntlProvider.

Translations were provided in messages.js file and they look like this:

export default { en: { message: '...some message', nested: { anotherMessage: '...another message', } } de: { // ... } } 

What I do is something like this:

// import messages from './messages.js' // Check the locale for the user (based on cookies or other things) const locale = ... // Get the required messages const messagesForLocale= = messages[locale]; // Supply the messages to the IntlProvider <IntlProvider locale={locale} messages={messagesForLocale}> // ... </IntlProvider> 

Then when I use FormattedMessage component I can't access the nested message (anotherMessage) with code like this:

<FormattedMessage id="nested.anotherMessage" ... /> 

But message is accessible.

Any ideas where I made the mistake, or maybe I'm missing something in the whole concept?

3 Answers 3

37

Since React Intl v2 no longer supports nested messages objects, the messages need to be flattened.

export const flattenMessages = ((nestedMessages, prefix = '') => { if (nestedMessages === null) { return {} } return Object.keys(nestedMessages).reduce((messages, key) => { const value = nestedMessages[key] const prefixedKey = prefix ? `${prefix}.${key}` : key if (typeof value === 'string') { Object.assign(messages, { [prefixedKey]: value }) } else { Object.assign(messages, flattenMessages(value, prefixedKey)) } return messages }, {}) }) // Use flattenMessages <IntlProvider locale={locale} messages={flattenMessages(messagesForLocale)}> 

refs:

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for that. We decided to go with I18next as this seems to be a more flexible library.
Didn't know that react-intl started at Yahoo!
19

react-intl does not support nested messages anymore. If you still want to organize your messages that way, you can use the flat library to correct your messages structure beforehand.

import flatten from 'flat' <IntlProvider locale={locale} messages={flatten(messagesForLocale)}> 

A contributor of react-intl claims that the main reason for only supporting a flat message structure is:

Simplicity and flexibility is the main reason. With the flat object, people can write whatever message ids/keys they want and they won't be interpreted with special semantics.

View the issue Support nested messages-object comment on GitHub.

Comments

2

Yes, customization using flattenMessages is the best way I found.

Here is the video demo for your reference.

https://egghead.io/lessons/react-convert-a-hard-coded-string-using-react-intl-formattedmessage

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.