mi18n-redux
v1.0.1
Published
MINTernationalization - i18n with redux made easy!
Downloads
6
Maintainers
Readme
MINTernationalization
i18n with redux made easy
npm i --save mi18n-redux
FAQ
Why this exists?
There are many great i18n libraries out there (links below). However, most of them use React components to show translated text (see next question) and when you have to use the function fallback you loose the auto rerender of translated components.
With this lib you can:
- always be sure that changing language will trigger update for those components that needs that and you're able to use functions for translation at the same time.
- namespace translators (useful when crating reusable components)
- download and set translations asynchronously
- use translations with parameters
- have pluralizable translations (multilingual)
- do all of that easily :)
Why not using components to show translated texts?
Components approach looks nice and consistent with the rest of your React application. However if you need to pass translated text in props you need a function fallback anyway. Function approach makes it consistent throughout the application and is understandable for everyone.
Usage
Add i18n reducer to your reducers:
import { reducer as i18nReducer } from 'mi18n-redux';
const rootReducer = combineReducers({
// ...
i18n: i18nReducer,
});
store = createStore(rootReducer);
translations example
const enTranslations = {
main: {
title: 'example title',
},
users: {
addUserButton: 'Add new user',
removeUserButton: 'Remove user',
removeUserAlert: {
title: 'Are you sure?',
text: 'This action cannot be undone',
},
},
translationWithDiacritics: 'ąóść'
}
Set language with translations:
import { setLanguage } from 'mi18n-redux';
store.dispatch(setLanguage('en', enTranslations));
or inside the component connected with redux state
import { setLanguage } from 'mi18n-redux';
class MyComponent {
// ... your component here
}
connect(
null,
{
setLanguage,
}
)(MyComponent); // now MyComponent can just call this.props.setLanguage('en', enTranslations) to change language
Connect component to translations:
import getT from 'mi18n-redux';
class MyComponent {
// ... your component here
}
connect(
state => ({
translator: getT(state.i18n),
namespacedTranslator: getT(state.i18n, 'users'),
lang: state.i18n.languageCode,
})
)(MyComponent);
Using translator
this.props.translator.t('main.title'); // example title
this.props.namespacedTranslator.t('addUserButton'); // Add new user
this.props.lang; // en
Using helper methods
this.props.translator.t('translationWithDiacritics'); // ąóść
this.props.translator.deburr().t('translationWithDiacritics'); // aosc
this.props.translator.deburr().toUpper().t('translationWithDiacritics'); // AOSC
this.props.translator.capitalize().t('main.title'); // Example title
this.props.translator.camelCase().t('main.title'); // exampleTitle
this.props.translator.lowerCase().t('main.title'); // example title
this.props.translator.snakeCase().t('main.title'); // example_title
this.props.translator.kebabCase().t('main.title'); // example-title
this.props.translator.startCase().t('main.title'); // Example Title
this.props.translator.upperCase().t('main.title'); // EXAMPLE TITLE
this.props.translator.upperFirst().t('main.title'); // Example title
API
reducer
import { reducer as mi18nReducer } from 'mi18n-redux'
- reducer that sets language and translation in redux store
- add it to redux store with the help of combineReducers function
setLanguage
import { setLanguage } from 'mi18n-redux'
- action creator which can be used to set language and translations
- arguments
- languageCode: string New language code (e.g. 'en')
- translations: object Object with new translations
SET_LANGUAGE_ACTION
import { SET_LANGUAGE_ACTION } from 'i18n-redux'
- Action type of action created by setLanguage action creator
- Can be used to create custom action creators or custom reducers
translationObject
plain JavaScript object (can be infinitely nested)
allowed fields
- nested object: object nested translation object
- pluralizable translation: array<string> array with translations
- translation: string translation
- translation with parameters: string translation in the form of 'Some unchangeable text and {{parameter}}!'
example in english:
const enTranslations = { main: { title: 'My awesome translated app' }, pluralizable: { dog: [ 'dog', 'dogs', ], person: [ 'person', 'people', ], }, withParams: { welcome: 'Hello {{user}}! How are you?', }, }
getT(state, [namespace])
import getT from 'mi18n-redux'
- arguments
- state: redux state i18n field from redux state
- namespace: string (default: null) path to the translations that translator will be limited to
- returns translator: object
- example
import getT from 'mi18n-redux'; class MyComponent { // ... your component here } connect( state => ({ translator: getT(state.i18n), namespacedTranslator: getT(state.i18n, 'users'), }) )(MyComponent);
translator
- methods
translator.translate(path, [replace, number])
: function- arguments
- path: string path to the given translation, must point to string or array not nested object
- replace: object parameters that should be replaced in the translations
- number: number number needed to decide which pluralizable translation to choose
- methods
translator.translate.capitalize()
: function returns translator object with capitalize flag addedtranslator.translate.toUpper()
: function returns translator object with uppercase flag addedtranslator.translate.toLower()
: function returns translator object with lowercase flag addedtranslator.translate.camelCase()
: function returns translator object with camelcase flag addedtranslator.translate.lowerCase()
: function returns translator object with lowercase flag addedtranslator.translate.lowerFirst()
: function returns translator object with lowerFirst flag addedtranslator.translate.titleCase()
: function returns translator object with titleCase flag addedtranslator.translate.deburr()
: function returns translator object with deburr flag added
- arguments
translator.t(path, [replace, number])
: alias fortranslator.translate
translator.namespace(namespace, [absolute])
: function- arguments
- namespace: string path to object that resulting translator should be limited to
- absolute: boolean (default: false) indicates whether namespace is absolute path or path relative to current namespace
- returns translator: object new instance of the translator with given namespace
- arguments
translator.n(namespace, [absolute])
: function alias fortranslator.namespace
translator.getTranslations(path, [absolute])
: function- arguments
- path: string (default: '') path to translation object we want to get
- absolute: boolean (default: false) indicates whether provided path is asbolute or relative to current namespace
- returns translations: object object with translations at given path
- arguments
translator.getLanguage()
- returns languageCode: string current language code
- fields
translator.pluralMap
: object object of functions (per language code) that takes number and returns index of corresponding plural form in pluralizable translation array- default
pluralMap = { default: number => number === 1 ? 0 : 1, pl: number => { const last = _.takeRight(number.toString().split(''), 1).join(''); const lastTwo = _.takeRight(number.toString().split(''), 2).join(''); if (number === 1) { return 0; } if ( (last === '2' || last === '3' || last === '4') && !(lastTwo === '12' || lastTwo === '13' || lastTwo === '14') ) { return 1; } return 2; }, en: number => number === 1 ? 0 : 1, }
TODO
- Make documentation easier to understand ;)
- Add example app