Skip to content

ReactLocalization

Staś Małolepszy edited this page Apr 7, 2020 · 3 revisions

The ReactLocalization class is reponsible for storing and caching the sequence of FluentBundles representing localization resources ordered according to the user's language preferences.

The ReactLocalization constructor takes as the first parameter an iterable of FluentBundle instances in order of the user's preferred languages. The FluentBundle instances will be used by the ReactLocalization instance to format translations. If a translation is missing in one bundle, thte ReactLocalization will fall back to the next one.

Array of Bundles

In the simplest scenario, the iterable of FluentBundles passed into ReactLocalization can be an array:

function generateBundles(currentLocales) {
    return currentLocales.map(locale => {
        const bundle = new FluentBundle(locale);
        for (const file of FILES[locale]) {
            const resource = new FluentResource(file);
            bundle.addResource(resource);
        }
        return bundle;
    });
}

let l10n = new ReactLocalization(generateBundles(['en-US']));

Iterator of Bundles

In order to avoid having to create all FluentBundle instances for all locales up front, it's a good idea to make bundles an iterator. The ReactLocalization instance will iterate over it (caching the items it yields) in case fallback is required.

function* generateBundles(currentLocales) {
    for (const locale of currentLocales) {
        const bundle = new FluentBundle(locale);
        for (const file of FILES[locale]) {
            const resource = new FluentResource(file);
            bundle.addResource(resource);
        }
        yield bundle;
    }
}

let l10n = new ReactLocalization(generateBundles(['en-US']));

Flexibility

The design of ReactLocalization requires a little bit of work from the developer. The iterable of FluentBundles needs to be created manually. This is intentional: it gives the most control to the developer with regards to the following three areas:

  • translations - the developer decides where translations are stored and how they're fetched,
  • language negotiation - the developer decides which factors are taken into account for the purpose of the language negotiation, as well as how exactly it's being done (we recommend @fluent/langneg),
  • custom extensions - the developer can pass options to the FluentBundle constructor to configure its behavior or to define functions available to translations.

In the future we might end up providing ready-made generators of the bundles iterable for the most common scenarios.

One limitation of the current design is that in asynchronous scenarios, all translations (including any fallback) must be fetched at once before <LocalizationProvider> is rendered. See the *-async examples in the examples/ directory for more information.

In the future we might be able to allow async fetching of fallback locales.