Edit in GitHubLog an issue


Internationalization (i18n) is a feature that lets you localize content for a culture, region, or language. This feature is often associated with localization (l10n), which is the process of transforming content for a specific locale.

Internationalization in Adobe Commerce and Magento Open Source versus PWA Studio#

The Adobe Commerce and Magento Open Source applications include an i18n feature that provides translated text to the frontend theme. This feature uses dictionary files inside language packages to provide translation data for the application when it renders a page. The language packages themselves are extensions the application installs using Composer.

For more information, see the core documentation topic: Translations overview.

The tight coupling between each applications' i18n feature and the frontend theme makes it difficult to use the same translation mechanisms in PWA Studio storefronts. Instead, PWA Studio provides its own i18n feature that follows a similar design as the one in Adobe Commerce and Magento Open Source.

How it works#

PWA Studio provides a context provider for translations called the LocaleProvider. This context provider contains translation data from dictionary files and supplies them to its child components.

The i18n feature in PWA Studio is an implementation of the react-intl library. The LocaleProvider component in PWA Studio wraps around the library's IntlProvider and provides it with translation data.

This library also provides formatMessage() and FormattedMessage to localize text in child components under LocaleProvider. You must at least supply values for id and a defaultMessage fallback when you use either the function or component.

The following code samples produce the same results:

Copied to your clipboard
1return (
2 <p className={classes.text}>
3 <FormattedMessage
4 id={"component.loremIpsum"}
5 defaultMessage={"Lorem Ipsum"}
6 />
7 </p>
Copied to your clipboard
1const translatedText = formatMessage({
2 id: "component.loremIpsum",
3 defaultMessage: "Lorem Ipsum",
6return <p className={classes.text}>{translatedText}</p>;

The i18n feature uses the id parameter to look up the localized text from the dictionary files, which the feature supplies to the LocaleProvider.

Translation dictionaries#

Translation dictionary files contain key/value pairs for localized text. PWA Studio's i18n feature uses a similar dictionary approach for translation files as Adobe Commerce and Magento Open Source, but instead of a CSV format, it uses JSON.

Filename format#

Dictionary files must be inside an i18n directory and use their target locale for their filename.

Instead of the standard ISO language tag the filename format follow's the following convention for specifying locale: <language id in lowercase>_<country id in uppercase>.json. For example: en_US.json, en_GB.json, fr_FR.json.

ID formats#

The JSON object's keys act as unique IDs for localized text. They map a placeholder string value in components to the actual rendered text.

PWA Studio recommends and uses a dot notation format in its components. This format uses the component name and descriptor to form the ID value.

Copied to your clipboard
2 "accountMenu.orderHistoryLink": "Order History",
3 "autocomplete.resultSummary": "{resultCount} items"

This approach helps identify which component renders the text and provides a unique value for the ID.

However, the i18n feature in PWA Studio does not limit you to the dot notation format. For example, in Adobe Commerce and Magento Open Source, the original en_US locale text identifies the translated text in the application.

Copied to your clipboard
2 "About Us": "About Us",
3 "Hi, {name}": "Hi, {name}"

PWA Studio's i18n feature allows you to use this notation in your own components and storefront. Both approach have their pros and cons, and developers are free to choose which approach works for them when they develop their own components and storefronts.

Message syntax#

The i18n feature accepts the same message syntax as the underlying react-intl library. Along with static text, this syntax supports variables, dates, and even conditional formatting.

To translate text with variables, pass in a mapping object to the values prop in the FormattedMessage component.

Copied to your clipboard
1return (
2 <FormattedMessage
3 id="component.greeting"
4 defaultMessage="Hi, {name}"
5 values={{
6 name: "Veronica",
7 }}
8 />

When using the formatMessage() function, pass in the mapping object as the second parameter.

Copied to your clipboard
1const text = formatMessage(
2 { id:"component.greeting", defaultMessage="Hi, {name}"},
3 { name: currentUser.firstname }

For more details, see the message syntax documentation at FormatJS.

Language packages and plugins#

Language packages provide translation data for one or more locales. They are also used to override the text in the same locale.

Unlike the Adobe Commerce and Magento Open Source applications, which install language packages through Composer, PWA Studio storefronts install language packages as NPM dependencies.

An NPM dependency is a language package if it meets the following criteria:

  • The package contains an intercept file
  • The intercept file sets the special feature i18n flag to true for the package
  • The package contains an i18n directory
  • The i18n directory contains a dictionary file with a locale formatted name

Build process#

To optimize runtime performance, the i18n feature compiles all the translation data during the build process.

The following is a high level summary of the actions the i18n feature takes to compile the translation data:

  1. Scans all i18n folders within installed modules that declare i18n support through the specialFeatures flag

  2. Scans the project's root directory for an i18n directory

  3. Generates an object with locales as keys that map to an array of files matching that locale

  4. Merges the files in the arrays to create a single dictionary object for a locale

    NOTE: The dictionary files in the project itself are the last files merged and the final overrides for translations.

  5. Creates a virtual module from this object that exposes a __fetchLocaleData__ function

  6. Generates a dynamic import in the application for the virtual module

Runtime process#

During runtime, the LocaleProvider component uses the __fetchLocaleData__ function to get the correct translation data for the current locale.

If a components changes the value of the current locale during runtime, the application sends a GraphQL query to verify the new value. Even if you install a language package plugin for a locale, you must enable the locale on the backend to use the translations in the storefront UI.

For example, if you use a store switcher and you provide an i18n/fr_FR.json file, you must enable the French locale in the backend application to make the store switcher work.

  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.