localize-toolkit
v2.3.0
Published
A localization library that uses React's context API and the Polyglot localization library to provide robust localization tools for React projects.
Downloads
10
Readme
Localize Toolkit
A localization library that uses React's context API and the Polyglot localization library to provide robust localization tools for React projects.
Features:
- Updates every translated phrase on language switch without remounting any components
- Caching phrases to avoid repeat fetching
- Static localization method for non-React files
Examples:
- Minimal Example
- The absolute bare-bones example of using Localize Toolkit
- "Kitchen Sink" Full Example
- A full example with faked API calls to fetch new languages
- Overlay Pattern Example
- A pattern to avoid remounting entirely, with an overlay for loading
- Pseudo Localization
- An example using pseudo localization (useful for testing)
The toolkit exposes 5 items: LocalizeProvider, LocalizeContext, Localize, useLocalize and staticTranslate. Expand the table of contents to jump to a specific item within these.
This package has a peer dependency on version
>16.8.0
ofreact
andreact-dom
, as it uses the Hooks API.This package has a dependency on
node-polyglot
. You may have some type issues if you are using TypeScript, since some of the types are fromnode-polyglot
. If this is an issue, you can install the@types/node-polyglot
as a dev-dependency:# yarn yarn add @types/node-polyglot -D # npm npm i @types/node-polyglot -D
LocalizeProvider
Localize provider contains the core functionality, and provides localize methods to both the LocalizeContext and the Localize component.
LocalizeProvider Props
getPhrases
: (language: string) => Promise<Phrases>
- Provide this prop to give an API endpoint that can be called with language.
This should asynchronously return a
Phrases
object.
noCache
: boolean
- By default, this is false. If set to true, none of the given or fetched
phrases will be cached within the provider. Any subsequent attempts to switch
to these languages will require a new phrases object be provided, or will make
a call to
getPhrases
.
pseudolocalize
: boolean
- By default, this is false. If set to true, will apply pseudo localization to all returned strings. This is for testing if your application can adapt to longer strings from other languages. Do not enable this in production.
Example Initialization
ReactDom.render(
<LocalizeProvider getPhrases={getLanguageAPI} noCache>
<App />
</LocalizeProvider>,
document.getElementById('root'),
);
LocalizeContext
All methods for localization and updating the LocalizeProvider are accessed through this Context.
LocalizeContext API
loading
: boolean
- Returns true if language is being fetched.
error
: Error | null
- Returns any errors encountered in setting the language.
currentLanguage
: string
- Returns the current language string.
isLanguageCached
: (language: string) => boolean
- Check if there are cached phrases for a given language string. This can be
called before
setLanguage
in order to check whether you will have to provide a phrases object.
setLanguage
: (language: string, phrases?: Phrases) => Promise<void>
Call this method to set the language. You must provide a language string (ex:
'en'
), and can optionally provide the corresponding language object. Once this method is called, there is a sequence of checks:If the phrases are provided, they will be used for the given language.
If no phrases are provided:
If the phrases aren't cached, fetch them from
getPhrases
prop in LocalizeProvider.Note: If no phrases are cached and no
getPhrases
prop is provided, an error will occur as the localize toolkit has no way to set the phrases for the specified language.If they are cached, use the cached phrases.
clearCache
: (language?: string) => void
- Clears a phrases object for the provided language from the cache if it exists. If no language is provided, this method clears all phrases from the cache.
t
: (phrase: string, options?: number | Polyglot.InterpolationOptions) => string;
- This is the Polyglot
t
method. For information on how to use this, check the documentation.
tt
: <Lang>(options?: number | Polyglot.InterpolationOptions): (...args: string[]) => string;
tt stands for typed-t and it has some special properties and use cases. If you have a TypeScript type definition for the structure of your phrases object you can use
tt
to throw errors if you use incorrect keys or change the keys in your language object. Every member of...args
must be a valid key in theLang
object provided (the actual type definition is much too verbose to write here, check out the source code if you want to see it).The use is slightly different than
t
. If you aren't sure which to use, or if you aren't using TypeScript, definitely uset
. This function is solely for ensuring type safety across large applications with rapidly changing phrase objects. Here's an example of the use cases compared tot
.// An example phrases object. const phrases = { hello_world: 'Hello World!', sizes: { mb: '%{smart_count}MB', }, names: { by_name: 'By %{name}', }, }; // Get the TypeScript type of the object. type Phrases = typeof phrases; // Examples using `tt`. const hiWrld = localize.tt<Phrases>()('hello_world'); const sizeMb = localize.tt<Phrases>(4)('sizes', 'mb'); const byName = localize.tt<Phrases>({name: 'John Doe'})('names', 'by_name'); // Examples using `t`. const hiWrld = localize.t('hello_world'); const sizeMb = localize.t('sizes.mb', 4); const byName = localize.t('names.by_name', {name: 'John Doe'});
As you can see, it is much more verbose, but it does help ensure you're correct:
const sizeMb = localize.tt<Phrases>(4)('sizes', 'mbzzzz'); // error: Argument of type '"mbzzzz"' is not assignable to parameter // of type '"mb" | undefined'. ts(2345) const sizeMb = localize.t('sizes.mbzzzz', 4); // no error thrown, as it's just a string.
Example Use
Here are some examples for using the localize context within your components.
How to consume context
There are three ways to use the localize context:
The exported useLocalize hook (a nice wrapper for the
useContext
hook so you don't need two imports):const localize = useLocalize(); localize.t('some_word');
The
useContext
hook (we recommend you use useLocalize instead though):const localize = useContext(LocalizeContext); localize.t('some_word');
The exported Localize component (more info below):
Example in Functional Component
import React, {useContext, useEffect} from 'react';
import {Localize, useLocalize} from 'localize-toolkit';
function MyComponent({}) {
const {setLanguage, t} = useLocalize();
useEffect(() => {
setLanguage('en');
}, [setLanguage]);
return (
<>
{/* To translate using the context: */}
{t('translate_token')}
{/* To translate as a JSX element: */}
<Localize t={'translate_token'} />
</>
);
}
Example in Class Component
import React, {Component} from 'react';
import {LocalizeContext, Localize} from 'localize-toolkit';
class MyComponent extends Component {
static contextType = LocalizeContext;
componentDidMount() {
const {setLanguage} = this.context;
setLanguage('en');
}
render() {
const {t} = this.context;
return (
<>
{/* To translate using the context: */}
{t('translate_token')}
{/* To translate as a JSX element: */}
<Localize t={'translate_token'} />
</>
);
}
}
Localize
Localize Props
t
: string
- The phrase string you wish to translate.
options
: number | Polyglot.InterpolationOptions
- Any options for the translated phrase. This acts the same as a second argument given to Polyglot. For information on how to use this, check the documentation;
transformString
: (translated: string) => string
- A function that takes in the translated string and returns the string that will be rendered by the component. For example, you can convert the translated string to uppercase.
Example Component
// Returns "HI JOHN" if language is "en" or "BONJOUR JOHN" if language is "fr".
<Localize
t="hi_name"
options={{name: 'John'}}
transformString={translated => translated.toUpperCase()}
/>
useLocalize
This is simply a hook to wrap useContext
. As such, these are equivalent:
useLocalize example:
import React from 'react';
import {useLocalize} from 'localize';
function Component() {
const localize = useLocalize();
}
useContext example:
import React, {useContext} from 'react';
import {LocalizeContext} from 'localize';
function Component() {
const localize = useContext(LocalizeContext);
}
As you can see, it just simplifies it slightly by allowing one less import and less code written.
staticTranslate
Note: This should only be used in cases where you are unable to use the context components. This would most likely be outside of React, such as inside of a Redux reducer. If you are using this inside a React file, you can probably use LocalizeContext or Localize instead.
You can call static translate in order to translate a phrase outside of React. For example, you can use it for translating something within Redux to be stored in the state. However is one important thing to consider: This will be a static translation. It will not update when you update the language using the Localize context.
Static translate only exposes the method t
, which exacly matches the t
method within Polyglot. For information on how to use this, check the
documentation. This method can be used as
follows:
// Returns "Hi John" if language is "en" or "Bonjour John" if language is "fr".
const translatedPhrase = staticTranslate.t('hi_name', {name: 'John'});