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. | Type | Description |
---|---|---|
1. | Storefront Files | JSON 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 File | JSON 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).
Language | Storefront | Schema |
---|---|---|
English | en.json | en.schema.json |
Hindi | hi.json | hi.schema.json |
Arabic | ar.json | ar.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. | Type | Description |
---|---|---|
1. | settings_data.json | Contains the saved values from the settings in settings_schema.json file. |
2. | settings_schema.json | Controls 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:
-
Use
useGlobalTranslation
fromfdk-core/utils
for consistent static content translation.import { useGlobalTranslation } from "fdk-core/utils";
const { t } = useGlobalTranslation("translation"); -
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 -
Format currencies using
currencyFormat
with dynamic locale values.currencyFormat(
product?.sizes?.price?.effective?.min,
product?.sizes?.price?.effective?.currency_symbol,
formatLocale(locale, countryCode, true)
); -
Use
useNavigate
fromfdk-core/utils
instead ofreact-router-dom
for navigation. This ensures standardized routing behavior across locales. -
Ensure date/time formatting uses the selected locale with
toLocaleString
.toLocaleString(formatLocale(locale, countryCode), options);
-
Use only the
action
prop inFDKLink
for navigation. For example,FDKLink
internally handle URL conversion.<FDKLink action={action} />
-
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; -
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
-
Always test for both LTR and RTL directions when adding styles.
- To simulate RTL mode, set the
dir
attribute tortl
on the<html>
tag during testing.
- To simulate RTL mode, set the
-
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
- Padding:
-
Use logical (direction-friendly) CSS values:
- Text alignment:
text-align: start
,text-align: end
- Float:
float: inline-start
,float: inline-end
- Text alignment:
-
Handle transforms carefully: When using
transform
properties likerotate
ortranslateX
, apply direction-specific variants if needed for RTL layouts. -
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:
-
Do not use both
to
andaction
props inFDKLink
.to
will be prioritized if both are provided, causing unexpected behavior. -
Do not manually convert actions using
convertActionToUrl
.// Avoid manual conversion
action={convertActionToUrl(action)}
to={convertActionToUrl(action)}
// Correct usage
action={action} -
Do not use object-style paths directly with
navigate
. Always manage locale-aware navigation through helper methods or hooks. -
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
-
Do not use
left
orright
CSS properties directly:- Avoid properties like
margin-left
,padding-right
, orleft: 10px
. - Use logical properties (
start
,end
) instead to maintain RTL compatibility.
- Avoid properties like
-
Do not hardcode directional icons: Avoid static icons like
→
. Instead, rotate icons dynamically usingtransform: rotateY(180deg)
when in RTL. -
Do not rely on
text-align: left
ortext-align: right
: Usetext-align: start
ortext-align: end
to enable automatic direction switching. -
Do not skip RTL testing: Many RTL-specific bugs only surface during proper
dir="rtl"
testing on<html>
or<body>
. -
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). -
Do not apply transforms assuming a fixed direction: Adjust transforms like
translateX(100%)
orrotate(15deg)
according to the active direction context. -
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. -
Do not ignore text alignment inside form inputs: Input text should align based on the language’s direction using
text-align: start
. -
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.