Universal internationalization (i18n) open source library for React
React translation module. Internationalize your great project. This library is part of translate-maker. Star this project on GitHub.
Install via npm.
npm install react-translate-maker
If you are using react >= 15.4.0 use version >= 0.3.0 otherwise use version < 0.3.0
Star this project on GitHub.
import React from 'react';
import Translate, { LocaleProvider, TranslateMaker } from 'react-translate-maker';
const translate = new TranslateMaker({
data: {
en_US: {
hello: 'Hello {$user.name}',
followers: `{$user.name} has {$user.followers, plural,
zero {no followers}
one {# follower}
{# followers}
}`
}
}
});
const user = {
name: 'Zlatko',
followers: 15,
};
React.render(
<LocaleProvider translate={translate} locale="en_US">
<div>
<h1><Translate path="hello" user={user} /></h1>
<Translate path="followers" user={user} />
</div>
</LocaleProvider>
);
The result will be
<div>
<h1>Hello Zlatko</h1>
Zlatko has 15 followers
</div>
If you want to load localisation files automatically with the require function you can use File adapter.
project
│ component.jsx
└──locales
│ en_US.js
export default {
gender: `{$gender, select, male {boy} female {girl}}`,
working: `{gender, $user1.gender as gender | capitalize} {$user1.name} is working with
{gender, $user2.gender as gender} {$user2.name}`
};
import React from 'react';
import Translate { LocaleProvider, TranslateMaker, Gender, FileAdapter } from 'react-translate-maker';
import path from 'path';
const translate = new TranslateMaker({
adapter: new FileAdapter({
path: path.join(__dirname, '/locales'),
});
});
const currentLocale = 'en_US';
const user1 = {
gender: Gender.MALE,
name: 'Zlatko',
};
const user1 = {
gender: Gender.FEMALE,
name: 'Livia',
};
React.render(
<LocaleProvider translate={translate} locale={currentLocale}>
<Translate path="working" user1={user1} user2={user2} />
</LocaleProvider>
);
The result will be
Boy Zlatko is working with girl Livia
If you want to use webpack with file adapter you need to use own function getFile. You need to use getFile instead of path because you need to change the webpack context.
import React from 'react';
import Translate { LocaleProvider, TranslateMaker, Gender, FileAdapter } from 'react-translate-maker';
const translate = new TranslateMaker({
adapter: new FileAdapter({
getFile: (locale, namespace) => require('./locale/' + locale),
});
});
const currentLocale = 'en_US';
const user1 = {
gender: Gender.MALE,
name: 'Zlatko',
};
const user1 = {
gender: Gender.FEMALE,
name: 'Livia',
};
React.render(
<LocaleProvider translate={translate} locale={currentLocale}>
<Translate path="working" user1={user1} user2={user2} />
</LocaleProvider>
);
import React, { Component } from 'react';
import Translate, { LocaleProvider } from 'react-translate-maker';
const currentLocale = 'en_US';
const data = {
en_US: {
inputSearch: 'Search',
},
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale}>
<Translate path="inputSearch" defaultValue="Search...">
{placeholder => (
<input type="text" placeholder={placeholder} />
)}
</Translate>
</LocaleProvider>
);
The result will be
<input type="text" placeholder="Search" />
import React, { Component } from 'react';
import { LocaleProvider, ProvideTranslate } from 'react-translate-maker';
class MyComponent extends Component {
render() {
const { translate } = this.props;
return (
<input type="text" placeholder={translate('inputSearch', 'Search...')} />
);
}
}
const currentLocale = 'en_US';
const data = {
en_US: {
inputSearch: 'Search',
},
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale}>
<ProvideTranslate>
{translate => (
<MyComponent translate={translate} />
)}
</T>
</LocaleProvider>
);
The result will be
<input type="text" placeholder="Search" />
Sometimes when you are using dot notation you can stack with long paths. For example: header.navigation.button.login. You can use component named Namespace which will help you to simplify your jsx file.
import React from 'react';
import Translate { LocaleProvider, Namespace } from 'react-translate-maker';
const currentLocale = 'en_US';
const data = {
en_US: {
header: {
navigation: {
title: 'MyProject',
button: {
login: 'Log In',
signup: 'Sign Up',
},
},
},
},
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale}>
<Namespace path="header.navigation">
<nav>
<ul>
<li><Translate path="button.login" /></li>
<li><Translate path="button.signup" /></li>
</ul>
</nav>
</Namespace>
</LocaleProvider>
);
import React from 'react';
import Translate { LocaleProvider, Namespace } from 'react-translate-maker';
const currentLocale = 'en_US';
const data = {
en_US: {
header: {
navigation: {
title: 'MyProject',
button: {
login: 'Log In',
signup: 'Sign Up',
},
},
},
},
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale}>
<Namespace path="header.navigation">
<h1><Translate path="title" /></h1>
<nav>
<Namespace path="button" compose>
<ul>
<li><Translate path="login" /></li>
<li><Translate path="signup" /></li>
</ul>
</Namespace>
</nav>
</Namespace>
</LocaleProvider>
);
Sometimes you need to provide HTML content.
import React from 'react';
import { LocaleProvider, Translate } from 'react-translate-maker';
const currentLocale = 'en_US';
const data = {
en_US: {
welcome: 'Welcome back {$user}. How is it going?',
},
};
const user = {
name: 'Zlatko',
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale}>
<Translate
path="welcome"
params={{
user: <b>{user.name}</b>
}} />
</LocaleProvider>
);
The result will be
<span>Welcome back <b>Zlatko</b>. How is it going?</span>
We are providing a component for the locale switch. It is a select with everything what do you need. You can use it in two ways. Here is first example.
import React, { Component } from 'react';
import Translate { LocaleProvider, LocaleSwitch } from 'react-translate-maker';
const data = {
en_US: {
language: 'Language',
button: {
login: 'Log In',
signup: 'Sign Up',
},
},
sk_SK: {
language: 'Jazyk',
button: {
login: 'Prihlasit sa',
signup: 'Odhlasit sa',
},
},
};
const locales = [{
label: 'English',
value: 'en_US',
}, {
label: 'Slovenčina',
value: 'sk_SK',
}];
const DEFAULT_LOCALE = 'en_US';
class App extends Component {
constructor(props, context) {
super(props, context);
this.state = {
locale: DEFAULT_LOCALE,
};
}
handleLocaleChange(locale) {
this.setState({
locale: locale,
});
}
render() {
const { data, locales } = this.props;
const currentLocale = this.state.locale;
return (
<LocaleProvider adapter={data} locale={currentLocale}>
<nav>
<ul>
<li><Translate path="button.login" /></li>
<li><Translate path="button.signup" /></li>
<li>
<Translate path="language" />
<LocaleSwitch locales={locales} onChange={this.handleLocaleChange.bind(this)}/>
</li>
</ul>
</nav>
</LocaleProvider>
);
}
}
React.render(<App data={data} locales={locales}/>);
As you can see in previous example. We are using onChange event. The main reason for that is that LocaleProvider is a controlled component. That means if you wanted to change property named locale of the LocaleProvider you need to change it directly in the render function.
If you want to use LocaleProvider as uncontrolled component you can do that. But all properties of the LocaleProvider will be used only as initialisation properties. Here is a second example (please take a loon on the property named controlled of the LocaleProvider).
import React, { Component } from 'react';
import Translate { LocaleProvider, LocaleSwitch } from 'react-translate-maker';
const data = {
en_US: {
language: 'Language',
button: {
login: 'Log In',
signup: 'Sign Up',
},
},
sk_SK: {
language: 'Jazyk',
button: {
login: 'Prihlasit sa',
signup: 'Odhlasit sa',
},
},
};
const locales = [{
label: 'English',
value: 'en_US',
}, {
label: 'Slovenčina',
value: 'sk_SK',
}];
const DEFAULT_LOCALE = 'en_US';
class App extends Component {
render() {
const { data, locales } = this.props;
const currentLocale = this.state.locale;
return (
<LocaleProvider adapter={data} locale={DEFAULT_LOCALE} controlled={false}>
<nav>
<ul>
<li><Translate path="button.login" /></li>
<li><Translate path="button.signup" /></li>
<li>
<Translate path="language" />
<LocaleSwitch locales={locales}/>
</li>
</ul>
</nav>
</LocaleProvider>
);
}
}
React.render(<App data={data} locales={locales}/>);
The main difference is that you are not able to change locale of the LocaleProvider with property named locale after first render.
Sometimes you need to provide HTML content.
import React from 'react';
import Translate, { LocaleProvider } from 'react-translate-maker';
const currentLocale = 'en_US';
const data = {
en_US: {
welcome: 'Welcome {$user.name | star}',
},
};
const filters = {
star: function star(value) {
return '*** ' + value + ' ***';
},
};
const user = {
name: 'Zlatko',
};
React.render(
<LocaleProvider adapter={data} locale={currentLocale} filters={filters}>
<Translate path="welcome" user={user} />
</LocaleProvider>
);
The result will be
<span>Welcome *** Zlatko ***</span>
Missing default translation for: ${path}
)Please take a look on translate-maker
Star this project on GitHub.
To run the test suite, first invoke the following command within the repo, installing the development dependencies:
npm install
Then run the tests:
npm test