Localization
Utilities to load and manage localization data.
Installation
yarn add @commercetools-frontend/l10n
Additionally, install the peer dependency (if not present):
yarn add react
Supported locales
en
de
es
fr-FR
pt-BR
zh-CN
To retrieve supported locales, use the getSupportedLocales
and getSupportedLocale
helper functions.
import {getSupportedLocales,getSupportedLocale,} from '@commercetools-frontend/l10n';// `getSupportedLocales` returns all supported localesconsole.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 localeconsole.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.
import { useCountries } from '@commercetools-frontend/l10n';function MyComponent() {const { isLoading, data: countries } = useCountries('en');if (isLoading) return <LoadingSpinner />;return <div>Countries: {JSON.stringify(countries)}</div>;// Countries format: { <countryCode>: <countryLabel> }// Example: { "de": "Germany" }"}
useCurrencies
A React hook that loads currency data based on the provided locale.
import { useCurrencies } from '@commercetools-frontend/l10n';function MyComponent() {const { isLoading, data: currencies } = useCurrencies('en');if (isLoading) return <LoadingSpinner />;return <div>Currencies: {JSON.stringify(currencies)}</div>;// Currencies format: { <currencyCode>: { label, symbol } }// Example: { "EUR": { "label": "Euro", "symbol": "€" } }}
useLanguages
A React hook that loads language data based on the provided locale.
import { useLanguages } from '@commercetools-frontend/l10n';function MyComponent() {const { isLoading, data: languages } = useLanguages('en');if (isLoading) return <LoadingSpinner />;return <div>Languages: {JSON.stringify(languages)}</div>;// Languages format: { <languageCode>: { 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.
import { useTimeZones } from '@commercetools-frontend/l10n';function MyComponent() {const { isLoading, data: timeZones } = useTimeZones('en');if (isLoading) return <LoadingSpinner />;return <div>Time zones: {JSON.stringify(timeZones)}</div>;// Time zones format: { <timezone>: { name, abbr, offset } }// Example:// { "Europe/Berlin": { "name": "Central European Time - Berlin", "abbr": "CEST", "offset": "+02:00" } }}
Utilities
Within the Common API Types in the Composable Commerce HTTP API is the LocalizedString
type.
In the following example, the Product
name is defined as a LocalizedString
:
{// `name` is a `LocalizedString`// as defined by https://docs.commercetools.com/api/projects/products#productdataname: {en: 'Milk';}}
However, the Composable Commerce GraphQL API represents the LocalizedString
type differently:
type TLocalizedString = {__typename?: 'LocalizedString';locale: string;value: string;};
{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.
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.
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 Composable Commerce GraphQL API for use in views with @commercetools-frontend/ui-kit
components.
// fetching a product from the Composable 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 shapeconst transformedProduct = applyTransformedLocalizedFields(product,fieldNameTransformMappings);// Finally, we are ready to render our form with the correctly shaped `name`return <LocalizedTextInput name="name" value={transformedProduct.name} />;
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.
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, where you need to prepare data for Composable Commerce GraphQL API mutations that expect LocalizedString
as the input type.
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. 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
property in the application context.
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:
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.
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 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.
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 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
.
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.
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.
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. This approach leverages the project languages, to ensure that the most appropriate localized value is displayed.
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 wantprojectLanguages: context.project.languages,}));return (<Text.Headline>{formatLocalizedString(product, {key: 'name',locale: dataLocale,fallback: NO_VALUE_FALLBACK,fallbackOrder: projectLanguages,})}</Text.Headline>);