Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best approach to multilingual react webapp

We want to have our backoffice for the main site as a multilingual solution for our users. We have already decided to use React + Redux for it, as it makes a lot of sense to use the already deployed API for several functionalities such as authorization and data fetching ..

I used a custom approach in the past, but it's so complex and maybe we are missing a best practices method here. The main site is already in 4 languages, and soon to grow into others.

I've taken a look at some of the ongoing libs, such as React-intl (https://github.com/yahoo/react-intl) and Airbnb Polyglot (http://airbnb.io/polyglot.js/)

What would be the best approach/lib/solution for building a multilingual site in React? (just on front-end, not an isomorphic app thou)

like image 682
elQueFaltaba Avatar asked Jul 04 '16 07:07

elQueFaltaba


People also ask

What is the best way to manage state in React?

Local state is most often managed in React using the useState hook. For example, local state would be needed to show or hide a modal component or to track values for a form component, such as form submission, when the form is disabled and the values of a form's inputs.

How do you serve a page with content in multiple languages React?

To change the language, just simply set the lang attribute. We can define it anywhere in the document, such as in the body, in the paragraph, in the heading, or in the span tag. But the best practice is to set the lang in the span tag.


2 Answers

You can use redux-polyglot to easily use Airbnb's Polyglot in a React/Redux application. (Note: I'm one of the authors)

It provides :

  • a reducer to store language and corresponding messages. You can supply both by either :
    • a middleware that you can configure to catch specific action, deduct current language and get/fetch associated messages.
    • direct dispatch of setLanguage(lang, messages)
  • a getP(state) selector that retrieves a P object that exposes 4 methods :
    • t(key): original polyglot T function
    • tc(key): capitalized translation
    • tu(key): upper-cased translation
    • tm(morphism)(key): custom morphed translation
  • a getLocale(state)selector to get current language
  • a translate higher order component to enhance your React components by injecting the p object in props

Simple usage example :

dispatch new language :

import setLanguage from 'redux-polyglot/setLanguage';

store.dispatch(setLanguage('en', {
    common: { hello_world: 'Hello world' } } }
}));

in component :

import React, { PropTypes } from 'react';
import translate from 'redux-polyglot/translate';

const MyComponent = props => (
  <div className='someId'>
    {props.p.t('common.hello_world')}
  </div>
);
MyComponent.propTypes = {
  p: PropTypes.shape({t: PropTypes.func.isRequired}).isRequired,
}
export default translate(MyComponent);

Please tell me if you have any question/suggestion !

like image 122
Jalil Avatar answered Oct 02 '22 20:10

Jalil


React-Intl and Polyglot are two most popular I18n libraries, according to my experiences with both of the libraries I prefer the simple solution of Polyglot than React-Intl approach. Polyglot is simple but has full features with interpolation and pluralization and the scaling is tested by Airbnb.

There are many libraries created to make it easier to use Polyglot in a React application, polyglot-react is one of them (I'm the author). It's a very simple higher order component that pass the polyglot instance down to the child components as a prop.

The usage is simple with 2 steps:

  1. Wrap the root component in the Provider component
import { Provider } from 'polyglot-react';
import App from './components/App';

const locale = "en";
const phrases = {
  "home.login": "Login",
  "home.signup": "Sign Up"
}

export default () => (
  <Provider locale={locale} phrases={phrases}>
    <App />
  </Provider>
);
  1. Decorate the child component
import React, { Component } from 'react';
import { withPolyglot } from 'polyglot-react';

class TodoList extends Component {
  render() {
    const { polyglot } = this.props;
    return (
      <div>
        <h1>{ polyglot.t("list.title") }</h1>
        <ul>
          {this.state.todos.map( todo => <Todo {...todo} /> )}
        </ul>
      </div>  
    );
  }
}

TodoList = withPolyglot()(TodoList);
export default TodoList;

This solution works on both client and server sides Javascript application.

like image 40
Ho Duc Ha Avatar answered Oct 02 '22 21:10

Ho Duc Ha