@serus/i18n
v0.1.92
Published
Internationalization helper
Downloads
5
Readme
i18n
Internationalization helper
Install
yarn add @serus/i18n
Overview
Roadmap
- initialLocale helper
- todo optimise default translations
- docs
- i18next plugin
- WTI plugin
- PhraseApp plugin
- enable use key context !!TBD
Usage
This library supports only JSX format (because of context). If you need to have access to string typed value, use Render props
or I18n.toString(<I18n ... />)
Common usage
import * as React from 'react';
import I18n from '@serus/i18n';
class Example extends React.Component {
render() {
return <I18n id="id1" d="Hello World!" />;
}
}
Render props
<I18n id="id1" d="Hello World!">
{placeholder => <input placeholder={placeholder} />}
</I18n>
I18n.toString()
this helper using ReactDOM to stringify component, but for consistent translation we need to have I18nContext available, so:
const placeholder = I18n.toString(<I18n id="key1" d="Defaut message" />);
console.log(typeof placeholder); // string
Context provider
Simple react context provider which enables you modularize your translations for each part separately (you neet to keep your current locale on your own, just pass locale
property to provider)
import * as React from 'react';
import I18n, { Provider as I18nProvider } from 'i18n';
class App extends React.Component {
render() {
return (
<I18nProvider locale="en">
<I18n id="id1" d="Hello World!" />
</I18nProvider>
);
}
}
Translation source
Best practice for internationationalization SPA is to serve translated app (per domain / per client locale accept-language header / ip pool / country / brand / etc. )
This lib supports production build with custom translation replaced right in js files (default localization is available instantly). Babel plugin will replace "default" messages and if user dont change his lang, app is delivered in right language as fast as possible.
In other case, we need to load translation, mostly in async mode because if server dont know which lang shoud be serverd, it will serve all supported languages and this behavior have negative inpact for page load speed.
So as a result internationalization provider expects Promise as source input (dynamic) dependency / code split / using cloud language tool wtc.)
Common usage
import { Provider, sourceFactory } from 'i18n';
const sourceMap = {
// static json
en: () => Promise.resolve({ key1: 'Val 1' }),
// use dynamic import a.k.a code split
sk: () => import('../i18n/sk.json').then(module => module.default)
}
const translationSource = sourceFactory(sourceMap);
<Provider locale="en" source={translationSource}>
Each promise will be fired once, and in time when needed.
Custom
You can implement your own localization resolver, expected interface is map of resolvers for each locale, get
& match
so:
const enSource = { ke1: 'Translated text' };
const skSource = { key1: 'Prelozeny text' };
{
en: {
get: (key: string) => enSource[key];
match: (search: string) => enSource; // *
},
sk: {
get: (key: string) => skSource[key];
match: (search: string) => skSource; // *
}
}
* match exists for ENUM keys
Enums
custom feature of this lib is enum key handling. Imagine, if you have some dynamic context like response message which depends on Promise response value, so you can put
const result = 'err1'
<I18n
d={{ done: "Wohoo!", err1: "Oops!", err2: "Yayy!" }}
id="enumMsg$"
v={result}
/>
those keys must endsWith $
& have d defined as object
& must pass v parameter
if you use enum keys, match
resolver will be applied, so you can search any keys by your own rules, or by default,
in case of render props usage, all keys which starts with %d%$
will be computed into single object by default match handler and passed as second parameter of render props
Render props
<I18n
d={{ done: "Wohoo!", err1: "Oops!", err2: "Yayy!" }}
id="enumMsg$"
v={result}
>
{(value, object) => <>
value: {value}
all values:
<pre>{JSON.stringify(object, null, 2)}</pre>
</>}
</i18n>
License
MIT © serus22