Skip to content
This repository was archived by the owner on Aug 28, 2021. It is now read-only.

un-ts/react-translator

Repository files navigation

react-translator

Greenkeeper badge Codecov Travis npm David David Dev code style: prettier

A deadly simple i18n translate plugin for React, ready for Server Side Rendering.

Demo

https://JounQin.github.io/react-translator

Related

VueTranslator

Usage

# npm npm install react-translator2 # yarn yarn add react-translator2
import { TranslatorContext, createTranslator, withTranslator } from 'react-translator2' const translator = createTranslator({ locale?: string, // set it on initialize or before first rendering translations?: { // 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 defaultLocale merge?: Function // `lodash.merge` for example, if you want to use component translator you must pass it }) const App = withTranslator(translations?)(({ t }) => <div>{t('msg')}</div>) const app = ( <TranslatorContext.Provider value={{ translator, toggleLocale }}> <App /> </TranslatorContext.Provider> )

translations is often generated via require.context provided by webpack from *.{locale}.i18n.json:

const context = require.context('.', true, /([\w-]*[\w]+)\.i18n\.json$/) const LOCALE_KEYS: { [key: string]: string[] } = {} const translations: { [locale: string]: { [key: string]: string } } = context.keys().reduce((modules: any, key: string) => { const module = context(key) const lang = key.match(/([\w-]*[\w]+)\.i18n\.json$/)[1] const matched = modules[lang] || (modules[lang] = {}) if (process.env.NODE_ENV === 'development') { const keys = LOCALE_KEYS[lang] || (LOCALE_KEYS[lang] || []) const moduleKeys = Object.keys(module) const duplicates = _.intersection(keys, moduleKeys) if (duplicates.length) { console.warn('detect duplicate keys:', duplicates) } keys.push(...moduleKeys) } Object.assign(matched, module) return modules }, {})

Then you need to use withTranslator to wrap your component to enable translator prop t and prop locale + defaultLocale, the reference value of t will never change what means there will be only one translator instance..

import { withTranslator } from 'react-translator2' export default withTranslator({ 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 parameter ignoreNonExist: boolean: $t('non-exist-key', null, true).

If you want to watch locale change in any component, you can use componentDidUpdate 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) } }

SSR related

You'd better to detect user custom locale via cookie and fallback to accept-language on first request.

And you need to generate a single translator instance for every user request (cache by locale would be better) via createTranslator, koa for example:

import { TranslatorContext, createTranslator } from 'react-translator2' app.use(async (ctx, next) => { const translator = createTranslator({ locale: string, // ctx.cookies.get('locale_cookie') defaultLocale: string, }) const app = ( <TranslatorContext.Provider value={{ translator, toggleLocale }}> <App /> </TranslatorContext.Provider> ) })

template syntax

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 }, }, })

Feature Request or Troubleshooting

Feel free to create an issue.

About

A deadly simple i18n translate plugin for React, ready for Server Side Rendering.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •