RetroMime
RetroMime

Reputation: 387

React - intl with external translation file

I'm trying to implement language support in the base version of a react app (create using npm create-react etc...)

I've installed react-intl but every time I search on google a guideline, I found a lot of not-working solutions.

What I want is using the classic <FormattedMessage id="myid" > in my component. Messages are stored in a SEPARATE file called './locales/en.json' or './locales/en.js'.

In my app.js im using

import {addLocaleData, IntlProvider} from 'react-intl';
import enLocaleData from 'react-intl/locale-data/en';

addLocaleData(enLocaleData);

and I used:

<IntlProvider locale='en' messages="i-dont-know-what-insert-here">
  <Index />
</IntlProvider>

I've tried a lot of solution.

FIRST APPROACH: en.json is built like this:

{
  "base.user":"Username"
  [...]
}

SECOND APPROACH: en.js is build like this:

export const ENGLISH = {
    lang: 'en',
    messages: {
        "base.user":"Username"
      [...]
    }
}

These are the example I found on google but I don't know how to use these files inside the app.

As next step, I have to allow the user to change language pressing a flag button but for now, I will happy to see translation files working.

Thanks.

Upvotes: 1

Views: 2680

Answers (1)

RetroMime
RetroMime

Reputation: 387

I've found a solution so I will post here for others.

FIRST: I've used second approach with lang.js files. So you have:

export const ENGLISH = {
    lang: 'en',
    messages: {
        "base.user":"Username"
      [...]
    }
}

In your app.js or in your root.js where you are using IntlProvider, include the files with:

import { ENGLISH } from './locales/en';

In you app.js (or your root js) use this:

class App extends Component {

  constructor(props)
  {
    super(props);

    this.state = {
        locale : 'en',
        messages : ENGLISH.messages
    }

    this.changeLanguage = this.changeLanguage.bind(this);
  }

and then:

<IntlProvider locale={this.state.locale} messages={this.state.messages}>
    <Index changeLanguage = {this.changeLanguage} />
</IntlProvider>

You can see the changeLanguage. That is the second question I post above. This is the changeLanguage method:

changeLanguage(lang)
  {
    switch(lang)
    {
      case "it": this.setState({local:lang}); this.setState({messages:ITALIAN.messages}); break;
      default: this.setState({locale:'en'}); this.setState({messages:ENGLISH.messages}); break;
    }
  }

Passing the method to the Index component, allow it to change language using some sort of event.

In your child Component (in my case Index) you have to define a changeLanguage method mapped on father method:

changeLanguage = (lang) => {
        this.props.changeLanguage(lang);
    }

Finally, if you have a flag button (o something else) you can use:

onClick={ () => this.changeLanguage('it') }

React will reload component automatically so every

<FormattedMessage ...

you have, will be translated dinamically

Upvotes: 3

Related Questions