Skip to content

LocalizationProvider

Adrian Gaudebert edited this page Oct 17, 2018 · 5 revisions

In fluent-react, all <Localized> components need access to an instance of the Localization class, the central localization store to which they subscribe. The <LocalizationProvider> component implements the provider pattern known from Redux. Taking advantage of React's context feature, it makes translations available to all localized elements in the app without passing them explicitly.

ReactDOM.render(
    <LocalizationProvider bundles={}></LocalizationProvider>,
    document.getElementById('root')
);

The LocalizationProvider component takes one prop: bundles. It should be an iterable of FluentBundle instances in order of the user's preferred languages. The FluentBundle instances will be used by Localization to format translations. If a translation is missing in one instance, Localization will fall back to the next one.

In its simplest form, bundles can be an array:

function generateBundles(currentLocales) {
    return currentLocales.map(locale => {
        const bundle = new FluentBundle(locale);
        bundle.addMessages(MESSAGES_ALL[locale]);
        return bundle;
    });
}

<LocalizationProvider bundles={generateBundles(['en-US'])}></LocalizationProvider>,

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 Localization class will iterate over it (caching the items it yields) in case fallback is required.

export function* generateBundles(currentLocales) {
    for (const locale of currentLocales) {
        const bundle = new FluentBundle(locale);
        bundle.addBundles(MESSAGES_ALL[locale]);
        yield bundle;
    }
}

<LocalizationProvider messages={generateBundles(['en-US'])}></LocalizationProvider>,

The bundles iterable

The design of the LocalizationProvider requires a little bit of work from the developer. The bundles iterable 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.

Clone this wiki locally