Skip to content

Latest commit

 

History

History
159 lines (112 loc) · 8.01 KB

File metadata and controls

159 lines (112 loc) · 8.01 KB

Localization

Most of the files in this folder are generated by react-intl CLI tool:

  • pwa/app/translations/en.json <- output of extracting the default messages, which you can send to your translators
  • pwa/app/translations/[locale].json <- the files that your translators make for the other locales
  • pwa/app/translations/compiled/[locale].json <- output of compiling the messages into AST format
    • Compiling helps improve the performance because it allows react-intl to skip the parsing step

Several npm scripts are available to you that make it easier to use the CLI tool. See pwa/package.json for more details.

  • To extract the default messages in your app, run npm run extract-default-translations to have all of the default messages extracted into their own JSON file.
  • To compile the translations from all of the locales, run npm run compile-translations.
  • To run both an extract and compile, run npm run build-translations

Supported Locales and Default Locale

The default locale, supported locales, and currency settings are defined in pwa/package.json in an object called l10n.

The locale ids in pwa/package.json follow the format supported by OCAPI and Commerce API: <language code>-<country code> as defined in this InfoCenter topic: OCAPI localization 21.8.

The currency code in l10n.supportedCurrencies and l10n.supportedLocales[n].preferredCurrency follow the ISO 4217 standard.

Important: The supported locale settings in pwa/package.json must match the locale settings for your B2C Commerce instance. For more information about configuring locales on a B2C Commerce instance, see this InfoCenter topic: Configure Site Locales.

Here’s the default locale configuration in pwa/package.json:

"l10n": {
    "supportedCurrencies": [
        "GBP",
        "EUR",
        "CNY",
        "JPY"
    ],
    "defaultCurrency": "GBP",
    "supportedLocales": [
        {
            "id": "en-GB",
            "preferredCurrency": "GBP"
        },
        {
            "id": "fr-FR",
            "preferredCurrency": "EUR"
        },
        {
            "id": "it-IT",
            "preferredCurrency": "EUR"
        },
        {
            "id": "zh-CN",
            "preferredCurrency": "CNY"
        },
        {
            "id": "ja-JP",
            "preferredCurrency": "JPY"
        }
    ],
    "defaultLocale": "en-GB"
}

Default Messages for Supported Locales

The default messages used by the locale selector are defined in the _app component:

export const defaultLocaleMessages = defineMessages({
    'en-GB': {defaultMessage: 'English (United Kingdom)'},
    'fr-FR': {defaultMessage: 'French (France)'},
    'it-IT': {defaultMessage: 'Italian (Italy)'},
    'zh-CN': {defaultMessage: 'Chinese (China)'},
    'ja-JP': {defaultMessage: 'Japanese (Japan)'}
})

These messages are used in places where the name of the locale is rendered (such as the locale selector).

When adding a new supported locale to pwa/package.json, you must update the defaultLocaleMessages in the _app component. Not doing so will result in errors when starting the app.

Formatting Messages

To support localization for multiple locales, write messages...

  • inline in the components, so it’s easier to see where in the page or component that they get used in
  • and in the default locale (for example, in English)

For example, in your React component, you can add formatted messages like intl.formatMessage({defaultMessage: '...'}) or <FormattedMessage defaultMessage="..." />

At the minimum, only defaultMessage is the required parameter. The message id is optional. If you don’t specify it, the id is auto-generated for you.

Workflow Between Developers and Translation Team

During your development, you extract and compile the messages and pass the generated JSON files to the translation team, as well as using the translated files in the app.

We’ve provided the following npm scripts to help you:

  • npm run build-translations to extract and compile default messages into the default locale
    • run this whenever you add a new formatted message to your components to update the default locale's translations

The above script can be further broken down into two sub scripts:

  • npm run extract-default-translations to extract the default messages
  • npm run compile-translations to compile all translation files in the pwa/app/translations/ folder into Abstract Syntax Tree (AST) format
    • react-intl can use this AST format to bypass the parsing step and thus, save a bit of time.

Whenever you run npm run prod:build, build-translations is run automatically in case you forgot to extract the latest messages.

Testing with a Pseudo Locale

To check whether you’ve wrapped all of the hardcoded strings with either intl.formatMessage() or <FormattedMessage /> , there’s a quick way to test that by running npm run start:pseudolocale. It runs your local dev server with the locale forced to the pseudo locale.

Loading the site in your browser, you can quickly see that those messages that have been formatted have a long SSS appended to them.

Summary

Putting all of the above together, the process for adding a new locale is as follows:

  1. Enable the new locale in Business Manager of your B2C Commerce instance
  2. Add the new locale to pwa/package.json
  3. In the _app component, add the new locale to the defaultLocaleMessages object and define a default message
  4. If the new locale is your new default locale:
    • Update your React components' default messages to the new default locale's language
    • In pwa/package.json, set the new default locale
    • Run npm run extract-default-translations to extract the new default locale's translations into pwa/app/translations/[defaultLocale].json
    • Send the extracted translations to your translation team
  5. Place the files you receive from your translation team into the pwa/app/translations/ folder
  6. Run npm run compile-translations

Tips

Here are a few useful things to know for developers.

User-Preferred Locales vs. App-Supported Locales

How a locale gets chosen depends on whether there’s a match found between 2 sets of locales. On a high level, it looks like this:

  1. Get the app-supported locales, which are defined in pwa/package.json (under l10n.supportedLocales ).
  2. Get the user-preferred locales, which are what the visitors prefer to see. The developer is responsible for fully implementing them in their own projects within the special _app component.
  3. If there’s a match between these 2 sets of locales, then the app would use it as the target locale.
  4. Otherwise, the app would fall back to its default locale (which is defined in package.json under l10n.defaultLocale ).

How to Detect the Active Locale

  • Within component render, useIntl hook is available to you: const {locale} = useIntl()
  • Within a page’s getProps there’s a params prop (specifically params.locale) coming from the routes that can tell you about which locale is being used in the current page URL.

Dynamic Loading of the Translation Files

Using dynamic import, regardless of how many locales the app supports, it would load only one locale at a time.

Initially, on app load, the translated messages are part of the server-rendered html. Afterwards on the client side, when dynamically changing the locale, the app would download the JSON file associated with that locale.

  • Each locale is a separate JSON file in the bundle. And it’s served with a 1-year cache header.
  • When a new bundle is deployed, you must download the JSON files again.

Link Component

The generated project comes with its own Link component. It automatically inserts the locale in the URLs for you.