# Localization
Utilities to load and manage localization data.
## Installation
```yarn
yarn add @commercetools-frontend/l10n
```
```npm
npm --save install @commercetools-frontend/l10n
```
Additionally, install the peer dependency (if not present):
```yarn
yarn add react
```
```npm
npm --save install react
```
## Supported locales
- `en`
- `de`
- `es`
- `fr-FR`
- `pt-BR`
- `zh-CN`
To retrieve supported locales, use the `getSupportedLocales` and `getSupportedLocale` helper functions.
```js
import {
getSupportedLocales,
getSupportedLocale,
} from '@commercetools-frontend/l10n';
// `getSupportedLocales` returns all supported locales
console.log(getSupportedLocales());
// ["en", "de", "es", "fr-FR", "pt-BR", "zh-CN"]
// `getSupportedLocale` returns the specified locale if it's supported; otherwise, it returns the default locale
console.log(getSupportedLocale('en')); // Output: 'en'
console.log(getSupportedLocale('sv')); // Output: 'en'
```
## Hooks
### useCountries
A React hook that loads country data based on the provided locale.
```jsx
import { useCountries } from '@commercetools-frontend/l10n';
function MyComponent() {
const { isLoading, data: countries } = useCountries('en');
if (isLoading) return ;
return
Countries: {JSON.stringify(countries)}
;
// Countries format: { : }
// Example: { "de": "Germany" }"
}
```
### useCurrencies
A React hook that loads currency data based on the provided locale.
```jsx
import { useCurrencies } from '@commercetools-frontend/l10n';
function MyComponent() {
const { isLoading, data: currencies } = useCurrencies('en');
if (isLoading) return ;
return Currencies: {JSON.stringify(currencies)}
;
// Currencies format: { : { label, symbol } }
// Example: { "EUR": { "label": "Euro", "symbol": "€" } }
}
```
### useLanguages
A React hook that loads language data based on the provided locale.
```jsx
import { useLanguages } from '@commercetools-frontend/l10n';
function MyComponent() {
const { isLoading, data: languages } = useLanguages('en');
if (isLoading) return ;
return Languages: {JSON.stringify(languages)}
;
// Languages format: { : { language, country } }
// Example with primary language: { "es": { "language": "Spanish" } }
// Example with language of a region:
// { "es-AR": { "language": "Spanish", "country": "Argentina" } }
}
```
### useTimeZones
A React hook that loads time zone data based on the provided locale.
```jsx
import { useTimeZones } from '@commercetools-frontend/l10n';
function MyComponent() {
const { isLoading, data: timeZones } = useTimeZones('en');
if (isLoading) return ;
return Time zones: {JSON.stringify(timeZones)}
;
// Time zones format: { : { name, abbr, offset } }
// Example:
// { "Europe/Berlin": { "name": "Central European Time - Berlin", "abbr": "CEST", "offset": "+02:00" } }
}
```
## Utilities
Within the [Common API Types](https://docs.commercetools.com/api/types.md) in the commerce HTTP API is the [`LocalizedString`](https://docs.commercetools.com/api/types.md#localizedstring) type.
In the following example, the `Product` name is defined as a `LocalizedString`:
```js title="Product (commerce HTTP API)"
{
// `name` is a `LocalizedString`
// as defined by https://docs.commercetools.com/api/projects/products#productdata
name: {
en: 'Milk';
}
}
```
However, the commerce GraphQL API represents the `LocalizedString` type differently:
```ts
type TLocalizedString = {
__typename?: 'LocalizedString';
locale: string;
value: string;
};
```
```js title="Product (returned from the commerce GraphQL API)"
{
nameAllLocales: [
{
locale: 'en',
value: 'Milk',
},
];
}
```
To distinguish these two formats, in the context of the Merchant Center, the graphql-shape is referenced as `LocalizedField`.
The following helper functions are provided to transform values between these two formats:
- `applyTransformedLocalizedStrings`
- `applyTransformedLocalizedFields`
- `transformLocalizedFieldToLocalizedString`
- `transformLocalizedStringToLocalizedField`
Additionally, the `formatLocalizedString` helper function converts a `LocalizedString` into a string, deriving the value based on the provided data locale and fallback order.
### applyTransformedLocalizedStrings
A helper function that transforms an object containing a `LocalizedString`-shaped value into an object with a list of `LocalizedField`-shaped values based on specified field name mappings.
The primary use case is to convert the `LocalizedString` field format [when integrating REST API responses within GraphQL queries](https://docs.commercetools.com/merchant-center-customizations/development/data-fetching.md#call-rest-apis-inside-your-graphql-queries).
```js title="Example usage"
const output = applyTransformedLocalizedStrings(
{
id: '1',
name: { en: 'Milk', de: 'Milch' },
},
[{ from: 'name', to: 'nameAllLocales' }]
);
console.log(output);
// { id: 1, nameAllLocales: [{ locale: 'de', value: 'Milch' }, { locale: 'en', value: 'Milk' }] }
```
### applyTransformedLocalizedFields
A helper function that transforms an object with a list of `LocalizedField` values into a `LocalizedString`-shaped object based on specified field name mappings.
```js title="Example usage"
const product = {
nameAllLocales: [
{
locale: 'en',
value: 'Milk',
},
{
locale: 'de',
value: 'Milch',
},
],
};
const fieldNameTransformationMappings = [
{
from: 'nameAllLocales',
to: 'name',
},
];
const transformedProduct = applyTransformedLocalizedFields(
product,
fieldNameTransformationMappings
);
console.log(transformedProduct);
// { name: { de: 'Milch', en: 'Milk' } }
```
The primary use case is transforming response fields shaped as `LocalizedFields` from the commerce GraphQL API for use in views with `@commercetools-frontend/ui-kit` components.
```jsx title="Example: Transforming response fields"
// fetching a product from the commerce GraphQL API returns a product with a `nameAllLocales`
const product = useMcQuery(ProductQuery, {
context: GRAPHQL_TARGETS.COMMERCETOOLS_PLATFORM,
});
// Since LocalizedTextInput accepts a value in the format `{ [key: string]: string }`,
// we transform our product to match the required shape
const transformedProduct = applyTransformedLocalizedFields(
product,
fieldNameTransformMappings
);
// Finally, we are ready to render our form with the correctly shaped `name`
return ;
```
### transformLocalizedFieldToLocalizedString
A helper function that transforms a list of `LocalizedField` values into a `LocalizedString`-shaped object.
This transformation is helpful when [converting data to initialize a form](https://docs.commercetools.com/merchant-center-customizations/development/forms.md#doctoformvalues).
```js title="Example usage"
const output = transformLocalizedFieldToLocalizedString([
{ locale: 'en', value: 'Milk' },
{ locale: 'de', value: 'Milch' },
]);
console.log(output);
// {en: 'Milk', de: 'Milch'}
```
### transformLocalizedStringToLocalizedField
A helper function that transforms a `LocalizedString` object into a list of `LocalizedField` values.
This transformation is helpful for [form conversions](https://docs.commercetools.com/merchant-center-customizations/development/forms.md#formvaluestodoc), where you need to prepare data for commerce GraphQL API mutations that expect `LocalizedString` as the input type.
```js title="Example usage"
const output = transformLocalizedStringToLocalizedField({
en: 'Milk',
de: 'Milch',
});
console.log(output);
// [{ locale: 'en', value: 'Milk' }, { locale: 'de', value: 'Milch' }]
```
### formatLocalizedString
A helper function that transforms a `LocalizedString` to a string, deriving the value from the provided data locale and fallback order. If the value cannot be derived, a fallback value is used instead.
The data locale is a value controlled by the Merchant Center user using the [data locale switcher](https://docs.commercetools.com/merchant-center/organizations-teams-projects.md#switch-between-projects-and-locales). The list of available options is derived from the list of languages specified in the project. The selected value can be read from the [`dataLocale`](https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-application-shell-connectors.md#datalocale) property in the [application context](https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-application-shell-connectors.md).
If the selected data locale does not match any of the localized string values, it is recommended to display a fallback value using the `formatLocalizedString` function.
#### Example usage
The following examples are based on the following `Product` object:
```js title="Product example"
const product = {
name: {
en: 'Milk',
de: 'Milch',
},
};
```
##### Scenario 1
The Merchant Center user has selected the `de` data locale. Since our example Product contains a value for the `de` locale, the localized value "Milch" is returned, as expected.
```js
const translatedName = formatLocalizedString(product, {
key: 'name',
locale: 'de',
});
console.log(translatedName);
// 'Milch'
```
##### Scenario 2
The Merchant Center user has selected the `sv` data locale, however, our example Product does not contain a value for this locale.
In this case, the `formatLocalizedString` function retrieves the next available value from `product.name` based on a predefined order of locales (further details in the [fallback order](https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-l10n.md#fallback-order) section). In this case, it falls back to the `en` locale and appends a hint `(EN)` to indicate that this value is from an alternate locale.
```js
const translatedName = formatLocalizedString(product, {
key: 'name',
locale: 'sv',
});
console.log(translatedName);
// 'Milk (EN)'
```
##### Scenario 3
The Merchant Center user has selected the `de-AT` data locale. While our example Product specifies a value for `de`, it does not specify a value for `de-AT`.
In this case, "Milch" is returned because the `formatLocalizedString` function extracts the [primary language subtag](https://en.wikipedia.org/wiki/IETF_language_tag) from the `locale` and then tries to match it to the available values. Since `de` is the primary language subtag of `de-AT`, the function selects `de` as the closest available value from `product.name`.
```js
const translatedName = formatLocalizedString(product, {
key: 'name',
locale: 'de-AT',
});
console.log(translatedName);
// 'Milch'
```
#### Fallback
To provide greater flexibility, the `formatLocalizedString` function allows you to specify a `fallback` value, which is used as a last resort.
```js
const translatedName = formatLocalizedString(product, {
obj: product,
key: 'name',
locale: 'sv',
fallback: '-',
});
```
If no explicit fallback is provided, and no value can be derived based on the locale and fallback order (see next section), an empty string is returned.
#### Fallback order
When no matching locale is found, the `formatLocalizedString` function selects the next available value from `product.name`.
To control the order in which the function attempts to find a match before resorting to the specified `fallback` value, you can specify a list of locales using `fallbackOrder`. This allows for customization of the fallback strategy to prioritize specific locales or values as needed.
```js
const translatedName = formatLocalizedString(product, {
obj: product,
key: 'name',
locale: 'sv',
fallbackOrder: ['en', 'de', 'es', 'it'],
fallback: '-',
});
```
#### When to use
When rendering a `LocalizedString` for a given `Resource`, it’s practical to use `formatLocalizedString` along with the [application context](https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-application-shell-connectors.md#application-and-custom-view-contexts). This approach leverages the project languages, to ensure that the most appropriate localized value is displayed.
```jsx
import Text from '@commercetools-uikit/text';
import { useApplicationContext } from '@commercetools-frontend/application-shell-connectors';
import { NO_VALUE_FALLBACK } from '@commercetools-frontend/constants';
const { dataLocale, projectLanguages } = useApplicationContext(
(applicationContext) => ({
dataLocale: applicationContext.dataLocale,
// The Application Context also exposes the languages that are defined on the Project settings
// we can rely on this to determine the fallback order.
// This helps with consistency, although you can specify the fallback order however you want
projectLanguages: context.project.languages,
})
);
return (
{formatLocalizedString(product, {
key: 'name',
locale: dataLocale,
fallback: NO_VALUE_FALLBACK,
fallbackOrder: projectLanguages,
})}
);
```
## Related pages
- [Section overview page](https://docs.commercetools.com/merchant-center-customizations.md)
- [Previous page: Internationalization](https://docs.commercetools.com/merchant-center-customizations/tooling-and-configuration/commercetools-frontend-i18n.md)