Translations
Merchant Center applications use react-intl
, a library built on top of the ECMAScript Internationalization API.
In the React components, you can use things like <FormattedMessage>
or intl.formatMessage
to render the correct translation message based on the active locale
.
We usually define a messages.js
file co-located to the React component using those messages. The file defines messages as following:
import { defineMessages } from 'react-intl';export default defineMessages({title: {id: 'StateMachines.ListView.title',description: 'The page title of state machines list',defaultMessage: 'State Machines',},});
This is the default message, which will be used in case there is no translation available for the given locale
.
Extracting messages for translations
To generate translation files, we provide a mc-scripts extract-intl
script, which will aggregate all react Intl messages into a core.json
file:
{"StateMachines.ListView.title": "State Machines"}
The core.json
is the so-called source file, which should be used as reference file for the translations in the other locales.
Depending on your translation process, you can decide to manage the translations in a separate service (at commercetools we use Transifex) or to manually provide the translations.
The mc-scripts extract-intl
command provides some extra options to deal with different scenarios.
Using the messages in the application
The JSON files containing the translations need to be loaded within the application. The <ApplicationShell>
expects a applicationMessages
prop that is used to load the messages in the react-intl
provider.
The applicationMessages
prop can either be a JSON object or a function returning a Promise with the loaded messages.
To keep the bundle size low, the application should only load the messages for a specific locale and not all of them. This can be achieved by using the Code-Splitting feature.
Given the translation messages are located in the i18n/data
folder, you can define a function to dynamically load the messages:
// entry-point.jsconst loadMessages = lang => {let loadAppI18nPromise;switch (lang) {case 'de':loadAppI18nPromise = import('../../i18n/data/de.json' /* webpackChunkName: "app-i18n-de" */);break;case 'es':loadAppI18nPromise = import('../../i18n/data/es.json' /* webpackChunkName: "app-i18n-es" */);break;default:loadAppI18nPromise = import('../../i18n/data/en.json' /* webpackChunkName: "app-i18n-en" */);}return loadAppI18nPromise.then(result => result.default,error => {console.warn(`Something went wrong while loading the app messages for ${lang}`,error);return {};});};const Application = () => (<ApplicationShell// other propsapplicationMessages={loadMessages}/>);