react-intl – accessing nested messages

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?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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:

Method 2

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.

Method 3

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


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x