Localization

You can localize your Catalyst storefront so that it appears in the shopper's preferred language throughout browsing and checkout experience. This provides a personalized shopping experience when you sell products internationally.

Note

Internationalization support in Catalyst is a work in progress. Full multilingual support in headless channels, like Catalyst, will be added in future releases. Currently, each Catalyst storefront can only support a single language. To display multiple languages, we recommend setting up a separate channel for each language. To fully localize a store for a language or region, you will need to customize product catalog and storefront content in the BigCommerce control panel.

Catalyst uses Next.js App Router Internationalization (i18n) (opens in a new tab) library to handle localization.

This guide describes how to provide static string translations for shoppers, including the required subdirectory, file structure and project configuration.

Required subdirectory

Each Catalyst project reserves a top level /messages/ subdirectory for localization. For your storefront to function properly, both the /messages/ subdirectory and the /messages/en.json file, which contains the default English phrases, must be present. You can localize static phrases by providing other JSON translation files in the /messages/ directory.

Note

Default language When you set up the project using the CLI (opens in a new tab), Catalyst hardcodes the default language file in US English. You can adjust the phrase strings in the resulting en.json file to meet your needs.

Translation file

To translate static phrases, create a JSON file for each language you choose to support. Each language that you want to support must have its own JSON file.

Name your translation files based on the BCP 47 specification (opens in a new tab) of language tags and country or region codes. For an overview of how these language tags are constructed, see Language tags in HTML and XML (opens in a new tab).

You can find a list of code subtags in the IANA Language Subtag Registry (opens in a new tab). These subtags are primitives that you can combine to create file name prefixes for individual regions. Here are some examples:

Localization file nameCorresponding regional language variantSubtags used
en.json (default)Englishen (English)
en-US.jsonUS Englishen (English) + US (United States)
en-AU.jsonAustralian Englishen (English) + AU (Australia)
es-US.jsonUS Spanishes (Spanish) + US (United States)
es-ES.jsonCastilian Spanishes (Spanish) + ES (Spain)
fr.jsonFrenchen (French)
fr-CA.jsonCanadian Frenchfr (French) + CA (Canada)

Translation keys

The JSON files should contain key-value pairs for each locale. You can define translations based on pre-defined keys used to translate the Catalyst storefront's basic ecommerce functionality (opens in a new tab). The translated values you specify will display to shoppers as static string translations.

Use the existing en.json file as a template for the schema. You can only provide translated values for the translation keys specified in the template.

For example, the en.json file contains the following translation keys:

"Home": {
  "Carousel": {
    "bestSellingProducts": "Best Selling Products",
    "featuredProducts": "Featured Products",
    "newestProducts": "Newest products"
  }
}

In your newly-created JSON file, add a translation of the value to the new locale.

"Home": {
  "Carousel": {
    "bestSellingProducts": "Produits les plus vendus",
    "featuredProducts": "Produits populaires",
    "newestProducts": "Produits les plus recentsProduits"
  }
}

Read more about i18n messages in next-intl docs (opens in a new tab).

i18n configuration

After you created a language file, add its name to the i18n.ts config file.

For example, if you created a fr.json file, include fr when you define the locales:

const locales = ['en', 'fr'] as const;

Using keys in React components

The following example shows how messages can be used in server component:

import { NextIntlClientProvider } from 'next-intl';
import { getMessages, getTranslations, unstable_setRequestLocale } from 'next-intl/server';
// ...
import { LocaleType } from '~/i18n';
 
interface Props {
  params: {
    locale: LocaleType;
  };
}
 
export default async function Home({ params: { locale } }: Props) {
  unstable_setRequestLocale(locale);
 
  const t = await getTranslations({ locale, namespace: 'Home' });
  const messages = await getMessages({ locale });
  // ...
 
  return (
    <div>
      <NextIntlClientProvider locale={locale} messages={{ Product: messages.Product ?? {} }}>
        <ProductCardCarousel
          products={featuredProducts}
          title={t('Carousel.featuredProducts')}
        />
      </NextIntlClientProvider>
    </div>
  );
}

Note

unstable_setRequestLocale Please pay attention to unstable_setRequestLocale call. You can read more in next-intl docs (opens in a new tab).

The following example shows usage in a nested client component:

'use client';
 
// ...
import { useTranslations } from 'next-intl';
 
export const AddToCart = () => {
  const t = useTranslations('Product.ProductSheet');
 
  return (
    <Button type="submit">
        t('addToCart')
    </Button>
  );
};

Routing and locale detection

Even though the next-intl library supports several locale detection strategies (opens in a new tab), Catalyst doesn't use any by default, as full internationalization support is still in progress. This strategy can be changed in the i18n.ts config file.

Currently, the shopper's browser preferences storefront detect locale by default. Catalyst uses the Accept-Language request HTTP header to determine which translation file to choose. If you do not have a JSON file matching the shopper's browser language, Catalyst will use the default English file.