Skip to main content

Multilingual Themes

The Multilingual feature in the Fynd Commerce platform enables sellers to offer their storefronts in multiple languages, enhancing accessibility for customers across diverse regions. Customers can easily switch languages through a click on the storefront and updating all text content to the selected language. This feature is implemented by enabling partners to configure translation keys within the theme code, ensuring that the storefront static content is rendered based on the customer’s language preference.

Directory Structure

theme
├── locale
│ │
│ ├── en.json
│ ├── en.schema.json
│ ├── hi.json
│ ├── hi.schema.json
│ ...

├── config
│ │
│ ├── settings_data.json
│ └── settings_schema.json
...

Locale Directory

The locale directory contains the files for a theme, which are used to provide translated static content. Locale files allow you to provide a translated experience in the theme editor and the storefront.

In addition to giving sellers a single place to easily edit words and phrases, locale files allow you to translate storefront static content and theme editor settings to multiple languages for sellers and customers.

Locale files allow sellers to translate their static content using a set of translated text strings available in multiple languages, such as English, Spanish, and Italian. You can leverage locale files to translate any content displayed in your storefront.

There are two types of locale files:

Sr. No.TypeDescription
1.Storefront FilesJSON files that contain a set of translations for text strings used throughout the storefront. They host translation strings for content displayed on the storefront throughout the theme.
2.Schema FileJSON files that contain a set of translations for text strings used throughout the theme editor.

Translation Key Structure in Locale Files

The translation keys in Locale files need to follow a structured naming convention to maintain consistency across multiple languages as follows:

  • Category: The top-level namespace that categorizes the type of content (e.g., resource).
  • Group: A sub-division under the category that narrows down the context (e.g., auth).
  • Description: The actual key representing the specific message to be translated (e.g., account_locked_message).
{
"resource": {
"auth": {
"account_locked_message": "Your Account is locked"
}
}
}

Nomenclature

A locale file name is composed of a base language and country of use. It must follow names as per IETF language tag nomenclature standards, which designates the first lowercase letter to stand for the language code (such as 'en' for English and 'hi' for Hindi).

LanguageStorefrontSchema
Englishen.jsonen.schema.json
Hindihi.jsonhi.schema.json
Arabicar.jsonar.schema.json

Example

Translation of storefront static content is achieved through translation keys in locale files. Instead of hardcoding text, partners map user-facing messages, ensuring that storefronts automatically render text based on the customer’s selected language.

1. Define Translation Keys

Each locale (such as English or Hindi) has its own JSON file inside the Locale directory, mapping keys to their corresponding translations. Each message displayed on the storefront is associated with a translation key. For example:

  • In locale/en.json file:

    "please_login_first": "Please Login first."
  • In locale/hi.json file:

    "please_login_first": "कृपया पहले लॉग इन करें।"

2. Retrieve Translated Text

In the example code shown below, multilingual support is implemented in the storefront theme using translation keys defined in the schema files.

When a customer is not logged in and attempts to add a product to their wishlist, a message prompts them to log in. Instead of hardcoding this message, the code uses the t() function to fetch the corresponding translation from the schema file based on the customer’s selected language.

The key resource.auth.login.please_login_first is mapped to different values in locale files such as en.json or hi.json file, ensuring that the message shown in the storefront appears in the appropriate language.

For example, in useProductDescription.jsx file:

function addToWishList(event) {
if (event) event.stopPropagation();
if (!LoggedIn) {
showSnackbar(t("resource.auth.login.please_login_first"));
navigate("/auth/login");
return;
}
// wishlist addition logic
}
  • If the customer has selected Hindi, the storefront displays “कृपया पहले लॉग इन करें।”
  • If the customer has selected English, the storefront displays “Please Login first.”
  • Switching languages from the storefront’s dropdown immediately triggers translations

Config Files

Config files define theme settings area of the theme editor.

There are two types of Config files:

Sr. No.TypeDescription
1.settings_data.jsonContains the saved values from the settings in settings_schema.json file.
2.settings_schema.jsonControls the organization and content of the theme settings area of the theme editor.

Example

In the below given example code, Schema translations are accessed with code in the following format:

  • To use the typography attribute, settings_schema.common.typography is used in en.schema.json and hi.schema.json files.
  • To use the font_header attribute, settings_schema.typography.font_header is used in en.schema.json and hi.schema.json files.
  • A t-filter (t:) translates text based on the customer’s selected language. The filter takes a translation key defined in the theme code and converts it into the appropriate localized text.
  "props": [
{
"type": "font",
"id": "font_header",
"category": "t:resource.settings_schema.common.typography",
"default": false,
"label": "t:resource.settings_schema.typography.font_header"
},
]
  • In en.schema.json file:

    "settings_schema": {
    "common": {
    "typography": "Typography",
    },
    }
    "typography": {
    "font_header": "Font Header",
    },
  • In hi.schema.json

    "settings_schema": {
    "common": {
    "typography": "टाइपोग्राफी",
    },
    "typography": {
    "font_header": "फ़ॉन्ट हेडर",
    },

Best Practices

To ensure an effective multilingual experience, follow the best practices mentioned below:

  1. Use useGlobalTranslation from fdk-core/utils for consistent static content translation.

    import { useGlobalTranslation } from "fdk-core/utils";
    const { t } = useGlobalTranslation("translation");
  2. Always replace static text with translation keys using the t method.

    <div>Something went wrong</div> // Avoid hardcoded text
    <div>{t("resource.common.error_message")}</div> // Use translation key
  3. Format currencies using currencyFormat with dynamic locale values.

    currencyFormat(
    product?.sizes?.price?.effective?.min,
    product?.sizes?.price?.effective?.currency_symbol,
    formatLocale(locale, countryCode, true)
    );
  4. Use useNavigate from fdk-core/utils instead of react-router-dom for navigation. This ensures standardized routing behavior across locales.

  5. Ensure date/time formatting uses the selected locale with toLocaleString.

    toLocaleString(formatLocale(locale, countryCode), options);
  6. Use only the action prop in FDKLink for navigation. For example, FDKLink internally handle URL conversion.

    <FDKLink action={action} />
  7. Handle redirections with correct locale context in manual redirects.

    const finalUrl = `${window.location.origin}${locale && locale !== 'en' ? `/${locale}` : ''}/cart/order-status/?${params.toString()}`;
    window.location.href = finalUrl;
  8. Use locale information when converting UTC dates to local dates.

    convertUTCDateToLocalDate(dateString, options, formatLocale(locale, countryCode));

Best Practices for Building Right-to-Left Compatible Themes

  1. Always test for both LTR and RTL directions when adding styles.

    • To simulate RTL mode, set the dir attribute to rtl on the <html> tag during testing.
  2. Use direction-aware CSS properties instead of physical direction properties:

    • Padding: padding-inline-start, padding-inline-end
    • Margin: margin-inline-start, margin-inline-end
    • Position: inset-inline-start, inset-inline-end
    • Border: border-inline-start, border-inline-end, border-start-start-radius, border-start-end-radius, border-end-start-radius, border-end-end-radius
  3. Use logical (direction-friendly) CSS values:

    • Text alignment: text-align: start, text-align: end
    • Float: float: inline-start, float: inline-end
  4. Handle transforms carefully: When using transform properties like rotate or translateX, apply direction-specific variants if needed for RTL layouts.

  5. Style pseudo-elements (::before and ::after) appropriately for both LTR and RTL modes to avoid visual inconsistencies.

Common Mistakes

When implementing multilingual support, avoid the following common mistakes:

  1. Do not use both to and action props in FDKLink. to will be prioritized if both are provided, causing unexpected behavior.

  2. Do not manually convert actions using convertActionToUrl.

    // Avoid manual conversion
    action={convertActionToUrl(action)}
    to={convertActionToUrl(action)}

    // Correct usage
    action={action}
  3. Do not use object-style paths directly with navigate. Always manage locale-aware navigation through helper methods or hooks.

  4. Do not hardcode locales or omit locales in redirects. Always append the correct locale dynamically when constructing URLs.

Common Mistakes while Building Right-to-Left Compatible Themes

  1. Do not use left or right CSS properties directly:

    • Avoid properties like margin-left, padding-right, or left: 10px.
    • Use logical properties (start, end) instead to maintain RTL compatibility.
  2. Do not hardcode directional icons: Avoid static icons like . Instead, rotate icons dynamically using transform: rotateY(180deg) when in RTL.

  3. Do not rely on text-align: left or text-align: right: Use text-align: start or text-align: end to enable automatic direction switching.

  4. Do not skip RTL testing: Many RTL-specific bugs only surface during proper dir="rtl" testing on <html> or <body>.

  5. Do not blindly use directional utility classes like .ml-4 or .pl-2: In utility-first frameworks (e.g., TailwindCSS), prefer logical utilities like .ps-4 (padding-start) or .pe-2 (padding-end).

  6. Do not apply transforms assuming a fixed direction: Adjust transforms like translateX(100%) or rotate(15deg) according to the active direction context.

  7. Do not use static images, backgrounds, or SVGs with baked-in directionality: Prefer CSS-based or dynamically mirrored SVG assets (scaleX(-1)) to adapt to direction changes.

  8. Do not ignore text alignment inside form inputs: Input text should align based on the language’s direction using text-align: start.

  9. Do not use physical-direction shorthand properties: Avoid shorthand like padding: 10px 20px 30px 40px; which assumes a fixed top-right-bottom-left sequence and does not adapt in RTL.


Was this section helpful?