- Notifications
You must be signed in to change notification settings - Fork1
A deadly simple i18n translate plugin for React, ready for Server Side Rendering.
License
un-ts/react-translator
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A deadly simple i18n translate plugin for React, ready for Server Side Rendering.
https://JounQin.github.io/react-translator
# npmnpm install react-translator2# yarnyarn add react-translator2
import{TranslatorContext,createTranslator,withTranslator}from'react-translator2'consttranslator=createTranslator({locale?:string,// set it on initialize or before first renderingtranslations?:{// If you want to define translations in component only, no need to set it on initialize[locale:string]:{[key:string]:string|array|object}},defaultLocale?:string,// when no value can be found in current locale, try to fallback to defaultLocalemerge?:Function// `lodash.merge` for example, if you want to use component translator you must pass it})constApp=withTranslator(translations?)(({ t})=><div>{t('msg')}</div>)constapp=(<TranslatorContext.Providervalue={{translator,toggleLocale}}><App/></TranslatorContext.Provider>)
translations
is often generated viarequire.context
provided bywebpack
from*.{locale}.i18n.json
:
constcontext=require.context('.',true,/([\w-]*[\w]+)\.i18n\.json$/)constLOCALE_KEYS:{[key:string]:string[]}={}consttranslations:{[locale:string]:{[key:string]:string}}=context.keys().reduce((modules:any,key:string)=>{constmodule=context(key)constlang=key.match(/([\w-]*[\w]+)\.i18n\.json$/)[1]constmatched=modules[lang]||(modules[lang]={})if(process.env.NODE_ENV==='development'){constkeys=LOCALE_KEYS[lang]||(LOCALE_KEYS[lang]||[])constmoduleKeys=Object.keys(module)constduplicates=_.intersection(keys,moduleKeys)if(duplicates.length){console.warn('detect duplicate keys:',duplicates)}keys.push(...moduleKeys)}Object.assign(matched,module)returnmodules},{})
Then you need to usewithTranslator
to wrap your component to enable translator propt
and proplocale
+defaultLocale
, the reference value oft
will never change what means there will be only one translator instance..
import{withTranslator}from'react-translator2'exportdefaultwithTranslator({zh:{message:'我的信息',},en:{message:'My Message',},})(({ t})=>(<div>{t('message',obj_params?)}{t('nested.message',arr_params?)}</div>))
If you are trying to get a non-exist key or value is undefined, you will get a warning in console on development. And if you want to ignore it, pass a third parameterignoreNonExist: boolean
:$t('non-exist-key', null, true)
.
If you want to watch locale change in any component, you can usecomponentDidUpdate
lifecycle:
componentDidUpdate(prevProps:TranslatorProps){if(prevProps.locale!==this.props.locale){// locale changed}}
If you want to change locale on client:
{changeLocale(){this.props.toggleLocale(locale)this.props.toggleDefaultLocale(defaultLocale)}}
You'd better to detect user custom locale via cookie and fallback toaccept-language on first request.
And you need to generate a single translator instance for every user request (cache by locale would be better) viacreateTranslator
,koa
for example:
import{TranslatorContext,createTranslator}from'react-translator2'app.use(async(ctx,next)=>{consttranslator=createTranslator({locale:string,// ctx.cookies.get('locale_cookie')defaultLocale:string,})constapp=(<TranslatorContext.Providervalue={{translator,toggleLocale}}><App/></TranslatorContext.Provider>)})
Translation key should be string, but.
(dot) will be parsed as nested key, it will also work in template!
t('a.b.c')// will try to find `a.b.c` on your custom transition, if a is falsy, will render undefined and try default locale// render `nested value`withTranslator({en:{a:{b:{c:'nested value',},},},})// render `nested template`t('a.b',{c:d:'nested template'})withTranslator({en:{a:{b:'{ c.d }'},},})
Array is also supported,.index
(dot) or[index]
can both be used!
// nested with array key and template// render `1`t('a.b[0]',[{a:1}])withTranslator({en:{a:{b:['{ 0.a }'],// do not use `[0].a` here, `0[a]` is also OK},},})
Feel free tocreate an issue.