# Translations Learn more about implementing multiple language support in your customizations. The Merchant Center is translated into several languages, for example, `en`, `de`, and `es`. The default language is `en`. The Merchant Center locale setting can be changed within the user profile page. When you develop a customization, you have the option to translate it in one or more languages. Translations are usually included as JSON files that are dynamically imported into the customization based on the user's locale. To facilitate the management of source messages and translations, we provide some built-in functionalities and tooling. ## Define source messages To get started, we recommend that you define source messages in the `messages.js` file next to your React component. ```js title="messages.js" import { defineMessages } from 'react-intl'; export default defineMessages({ title: { id: 'Channels.title', defaultMessage: 'Channels list', }, }); ``` Source messages are defined as named objects by [`react-intl`](https://formatjs.github.io/docs/react-intl), a library with React abstractions on top of the [ECMAScript Internationalization API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl). We recommend that you familiarize yourself with the [ICU Message syntax](https://formatjs.github.io/docs/core-concepts/icu-syntax) to take advantage of the different syntax features. The source messages can then be used in your React components. ## Consume messages as React components The `react-intl` library provides several React components to render the message, like ``. ```js title="channels.js" highlightLines="1,10" import { FormattedMessage } from 'react-intl'; import messages from './messages'; const Channels = () => { // ... return ( ) }; ``` Most of the [UI Kit](https://uikit.commercetools.com/) components support formatting messages via the prop `intlMessage`. This lets you pass your raw message and the component takes care of rendering the message. ```js title="channels.js" highlightLines="9" import { FormattedMessage } from 'react-intl'; import messages from './messages'; const Channels = () => { // ... return ( ); }; ``` ## Consume messages as React Hooks The `react-intl` library also provides an [imperative API](https://formatjs.github.io/docs/react-intl/api) approach via `useIntl`, which exposes an `intl` object with several formatting methods. Using the `intl` object is usually necessary for props that only accept strings, for example `aria-label`, `title`, etc. ```js import { useIntl } from 'react-intl'; const Button = () => { const intl = useIntl(); return ( ); }; ``` ## Extract messages for translations To generate translation files, you can use the official `@formatjs/cli` package to [extract source messages](https://formatjs.github.io/docs/tooling/cli#extraction) into a `core.json` source file. For example: ```console noPromptLines="2-3" formatjs extract --out-file=./src/i18n/data/core.json 'src/**/messages.js' ``` The `core.json` is the so-called source file, which should be used as the reference file for the translations in the other locales. As a convention, we store the translation files in an `i18n` folder: ``` └── src └── i18n └── data ├── core.json ├── en.json └── de.json ``` Depending on your translation tool, you may need to transform the extracted messages to the appropriate format. To do this, you can write a [formatter file](https://formatjs.github.io/docs/tooling/cli#--format-path) and pass it as the `--format` option to the script. ```console noPromptLines="2-3" highlightLines="2" formatjs extract --format=./intl-transformer.js --out-file=./src/i18n/data/core.json 'src/**/messages.js' ``` At commercetools, we use [Transifex](https://www.transifex.com/) as our translation tool. Therefore, in our applications we generate a `core.json` file with the key being the message id and the value being the default message. ```json { "Channels.title": "Channels list" } ``` ## Import translations The JSON files that contain the translations need to be loaded within the customization. - For Custom Applications: the [``](/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-application-shell.md#applicationshell) expects a `applicationMessages` prop that is used to load the messages in the `react-intl` provider. - For Custom Views: the [``](/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-application-shell.md#customviewshell) 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 small, 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](https://reactjs.org/docs/code-splitting.html) feature. If the translation messages are located in the `i18n/data` folder, you can define a function to dynamically load the messages. ```js title="load-messages.js" import { parseChunkImport, mapLocaleToIntlLocale, } from '@commercetools-frontend/i18n'; const getChunkImport = (locale) => { const intlLocale = mapLocaleToIntlLocale(locale); switch (intlLocale) { case 'de': return import( /* webpackChunkName: "app-i18n-de" */ './i18n/data/de.json' ); default: return import( /* webpackChunkName: "app-i18n-en" */ './i18n/data/en.json' ); } }; const loadMessages = async (locale) => { try { const chunkImport = await getChunkImport(locale); return parseChunkImport(chunkImport); } catch (error) { console.warn( `Something went wrong while loading the app messages for ${locale}`, error ); return {}; } }; export default loadMessages; ``` The starter templates already provide this function. In the `entry-point.jsx` component you can then pass the function to the `applicationMessages` prop: ```jsx title="entry-point.jsx" import loadMessages from '../../load-messages'; const EntryPoint = () => ( ); ``` ```jsx title="entry-point.jsx" import loadMessages from '../../load-messages'; const EntryPoint = () => ( ); ``` ## Related pages - [Area overview page with navigation](/merchant-center-customizations.md) - [Previous page: Testing](/merchant-center-customizations/development/testing.md) - [Next page: Permissions](/merchant-center-customizations/development/permissions.md)