Skip to content

Instantly share code, notes, and snippets.

@ivosabev
Created March 8, 2017 09:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivosabev/299aa8c8de135fbe1ad7774631077478 to your computer and use it in GitHub Desktop.
Save ivosabev/299aa8c8de135fbe1ad7774631077478 to your computer and use it in GitHub Desktop.
Basic react-intl setup

A very basic react-intl setup.

  1. We have a HOC withIntl that injects t() as prop to our localized components. t() is just a wrapper around the react-intl formatMessage function.
  2. We have a IntlProvider component that wraps our whole application and provides the translated messages and loads the locale data. We are using Relay to get the locale of the user, but you can do it any way you want.
  3. Sample de.js that hold our German translations.
  4. In our Example component we can call the t(). We can pass values or not depending on the translated message.

We are using the english translations (Hello, {name}) as an ID, but you can have arbitrary IDs (hello_firstName).

Read the docs: https://github.com/yahoo/react-intl

export default {
"Hello, {name}": "Guten Tag, {name}",
}
import React from 'react';
import {withIntl} from 'ufleet-intl';
const Example = (props) => <div>{props.t('Hello, {name}', {name: 'React'})}</div>;
export default withIntl(Example);
import React. {Component} from 'react';
import {addLocaleData, IntlProvider as ReactIntlProvider} from 'react-intl';
import bg from 'react-intl/locale-data/bg';
import de from 'react-intl/locale-data/de';
import en from 'react-intl/locale-data/en';
import Relay from 'react-relay';
import langs from 'ufleet-intl/lib/langs';
//
addLocaleData([...bg, ...de, ...en]);
class IntlProvider extends Component {
render() {
const {viewer} = this.props;
const locale = viewer.settings.locale || 'en';
const messages = langs[locale] || langs['en'];
return (
<ReactIntlProvider locale={locale} messages={messages}>
{this.props.children}
</ReactIntlProvider>
);
}
}
export default Relay.createContainer(IntlProvider, {
fragments: {
viewer: () => Relay.QL`
fragment on User {
settings {
locale
}
}
`,
},
});
import React, {Component} from 'react';
import {injectIntl} from 'react-intl';
const withIntl = WrappedComponent => injectIntl(
class extends Component {
static displayName = `withIntl(${(Component.displayName || Component.name) || 'Component'})`;
translate = (id = null, values = {}) => {
const {intl} = this.props;
return intl.formatMessage({
id: id,
defaultMessage: id,
}, values);
}
render () {
return <WrappedComponent
t={this.translate}
{...this.props}
/>
}
}
);
export default withIntl;
@RStankov
Copy link

RStankov commented Mar 8, 2017

Nice :)

My first thought is to extract something like:

<T name={name}>Hello, [name]</T>

I guess there would be some setting to use [] for interpolation instead of the {} in react-intl.

const T = ({ t, children, ...params}) => {
  return t(children, params)
};

// optimize rendering
// ensure children is only strings

export default withIntl(T);

@ivosabev
Copy link
Author

ivosabev commented Mar 8, 2017

In react-intl they already have such tag it is called <FormattedMessage>, but then you have to use intl.formatMessage function in the non JSX code. We didn't want to use a tag in one place and a function in another, so we opted for the wrapper that provides a function everywhere.

https://github.com/yahoo/react-intl/wiki/Components#formattedmessage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment