Skip to main content

Multi-Language Support

Multi-language support allows users to use an application in the language and regional format they understand best.

Translation key + active locale + dynamic values
↓
Localized UI message

For example, the same key can produce different text:

en → "Log in"
hi → "लॉग इन करें"
fr → "Se connecter"

Instead of hardcoding visible text inside components, the application stores messages separately and resolves them for the selected locale.

Core idea: Components should describe which message they need; the localization layer decides how that message is presented for the user's locale.


1. Internationalization vs Localization​

The two terms are related but not identical.

TermMeaning
Internationalization (i18n)Designing the application so it can support different languages, regions, and writing systems
Localization (l10n)Adapting the application for a particular locale, including translations and cultural conventions

The numbers in i18n and l10n represent the letters omitted between the first and last characters.

Localization is more than translating words. It can also affect:

  • dates and times;
  • numbers, currencies, and units;
  • plural rules;
  • text direction;
  • sorting and search;
  • names, addresses, images, and culturally appropriate content.

2. Language Is Not the Same as Locale​

A language identifies how people communicate. A locale also captures regional conventions.

en      → English language
en-US → English used in the United States
en-GB → English used in the United Kingdom
pt-BR → Portuguese used in Brazil

Two users may read the same language but expect different date or currency formats.

Use standard BCP 47 language tags such as en, en-IN, or fr-FR rather than inventing identifiers.


3. Basic Architecture​

A multilingual interface usually has four parts:

User or browser chooses a locale
↓
Locale manager stores the active locale
↓
Translation service loads matching resources
↓
Components request messages by stable keys
↓
Dates, numbers, plurals, and layout are localized

Example translation resources:

translations.js
export const translations = {
en: {
welcomeTitle: "Welcome",
loginButton: "Log in",
},
hi: {
welcomeTitle: "स्वागत है",
loginButton: "लॉग इन करें",
},
};

Example component:

import { useState } from "react";
import { translations } from "./translations";

export default function App() {
const [locale, setLocale] = useState("en");
const messages = translations[locale] ?? translations.en;

return (
<main>
<h1>{messages.welcomeTitle}</h1>
<button>{messages.loginButton}</button>

<label>
Language
<select
value={locale}
onChange={event => setLocale(event.target.value)}
>
<option value="en">English</option>
<option value="hi">हिन्दी</option>
</select>
</label>
</main>
);
}

This is enough for a small application, prototype, or learning project.


4. Why Applications Use an i18n Library​

A simple object lookup becomes harder to maintain when an application needs:

  • hundreds or thousands of messages;
  • interpolation and plural rules;
  • fallback languages;
  • translations split by page or feature;
  • asynchronous resource loading;
  • language detection and persistence;
  • integration with a translation workflow.

Libraries such as i18next with react-i18next provide these capabilities without requiring the application to build them from scratch.

Example Resource Structure​

public/
└── locales/
├── en/
│ ├── common.json
│ └── checkout.json
├── fr/
│ ├── common.json
│ └── checkout.json
└── hi/
├── common.json
└── checkout.json
locales/en/common.json
{
"navigation": {
"home": "Home",
"orders": "Orders"
},
"greeting": "Hello, {{name}}!"
}
locales/hi/common.json
{
"navigation": {
"home": "होम",
"orders": "ऑर्डर"
},
"greeting": "नमस्ते, {{name}}!"
}

React Usage​

import { useTranslation } from "react-i18next";

function Header({ user }) {
const { t, i18n } = useTranslation("common");

return (
<header>
<p>{t("greeting", { name: user.name })}</p>

<button onClick={() => i18n.changeLanguage("hi")}>
हिन्दी
</button>
</header>
);
}

The component uses a stable key while the library handles lookup, interpolation, loading, and re-rendering after a locale change.


5. Choosing the Initial Locale​

A predictable priority order avoids surprising the user.

1. Explicit account preference
2. Previously saved device preference
3. Locale in the URL
4. Browser language preference
5. Application default

The exact order is a product decision. For a public localized website, the URL may have higher priority. For a signed-in application, the account preference may be more important.

const supportedLocales = ["en", "fr", "hi"];

function getSupportedLocale(candidate) {
const baseLanguage = candidate?.split("-")[0];

return supportedLocales.includes(candidate)
? candidate
: supportedLocales.includes(baseLanguage)
? baseLanguage
: "en";
}

Always validate a detected locale against the languages the application actually supports.


6. Locale-Aware Formatting with Intl​

Translation files should contain messages, but dates, numbers, lists, and currencies should be formatted with locale-aware APIs.

const locale = "en-IN";

const price = new Intl.NumberFormat(locale, {
style: "currency",
currency: "INR",
}).format(125000);

const deliveryDate = new Intl.DateTimeFormat(locale, {
dateStyle: "long",
}).format(new Date("2026-09-20"));

Possible output:

₹1,25,000.00
20 September 2026

Useful JavaScript internationalization APIs include:

APIPurpose
Intl.NumberFormatnumbers, percentages, units, and currencies
Intl.DateTimeFormatdates and times
Intl.RelativeTimeFormatmessages such as “2 days ago”
Intl.ListFormatlocale-correct lists
Intl.Collatorlocale-aware sorting and comparison
Intl.PluralRulesselecting locale-specific plural forms

Do not manually create formats such as DD/MM/YYYY or place currency symbols with string concatenation. The correct convention depends on the locale.


7. Interpolation and Pluralization​

Interpolation​

Keep a complete sentence in the translation resource and insert dynamic values through placeholders.

{
"orderReady": "Order {{orderId}} is ready for {{customerName}}."
}
t("orderReady", {
orderId: order.id,
customerName: customer.name,
});

Avoid assembling translated sentences from fragments:

// Avoid: word order may differ between languages.
`${t("hello")} ${name} ${t("welcomeBack")}`

Pluralization​

Languages do not all use the same singular and plural rules. Let the i18n library select the correct form from the count.

{
"cartItem_one": "{{count}} item",
"cartItem_other": "{{count}} items"
}
t("cartItem", { count: cartItems.length });

Do not assume that every language has only two forms or that adding s creates a plural.


8. Right-to-Left Languages​

Arabic, Hebrew, and some other languages are written primarily from right to left.

Update the document language and direction whenever the locale changes:

const rtlLanguages = new Set(["ar", "he", "fa", "ur"]);
const language = locale.split("-")[0];

document.documentElement.lang = locale;
document.documentElement.dir = rtlLanguages.has(language) ? "rtl" : "ltr";

Prefer CSS logical properties so the same styles adapt automatically:

.card {
margin-inline-start: 1rem;
padding-inline: 1.25rem;
border-inline-start: 4px solid rebeccapurple;
}

Use inline-start and inline-end rather than assuming left and right. Also verify icons, navigation order, mixed-direction text, tables, and animations in an actual RTL locale.


9. Loading and Scaling Translation Resources​

Bundling every language into the initial JavaScript increases download size even though a user usually needs only one locale.

For larger applications:

  • split messages into feature-based namespaces;
  • load the active language on demand;
  • load a namespace when its route is visited;
  • cache versioned translation files;
  • prefetch a likely next locale only when beneficial.
Open checkout route
↓
Load current locale's checkout namespace
↓
Render localized checkout screen

Provide a loading state or server-render the required messages so untranslated keys do not flash on the screen.


10. Fallback Strategy​

A missing translation should degrade predictably.

fr-CA checkout.pay
↓ missing
fr checkout.pay
↓ missing
en checkout.pay
↓ missing
Visible development warning or safe placeholder

A fallback is a safety net, not a replacement for translation quality checks. Track missing keys so incomplete locales are discovered before release.

Avoid silently showing an empty string because users cannot understand what went wrong and automated tests may miss it.


11. Accessibility and SEO​

Accessibility​

  • Set the root <html lang="..."> value correctly.
  • Add lang to passages written in a different language.
  • Do not place important translated text only inside images.
  • Translate accessible names, form errors, alternative text, and announcements.
  • Test keyboard navigation and screen-reader output after layout direction changes.

SEO for Public Pages​

Public content often uses locale-specific URLs:

/en/products/42
/fr/products/42
/hi/products/42

Each localized page should have the correct document language, localized metadata, canonical strategy, and hreflang links where appropriate. Server rendering or static generation also prevents crawlers and users from initially receiving the wrong language.

Internal dashboards may not need localized URLs because search indexing and link sharing are different product requirements.


12. Translation Workflow​

As the product grows, localization becomes a content workflow as well as a coding concern.

Developer adds a stable key and source message
↓
Translation platform or resource file receives it
↓
Translators add locale-specific messages
↓
Automated checks validate keys and placeholders
↓
Reviewers test the message in the real interface

Stable keys should describe meaning rather than visual position.

Good: checkout.payment.submit
Good: profile.deleteAccount.confirmation

Weak: blueButtonText
Weak: homepageText3

Give translators context for ambiguous messages, variables, character limits, and where the text appears.


13. Testing Multi-Language Support​

Test more than whether a key returns a string.

Test typeWhat to verify
Unitlocale selection, fallback rules, and formatting helpers
Integrationswitching language re-renders the page and persists preference
Visuallong translations do not overflow or hide controls
RTLlayout direction, icons, ordering, and mixed-direction text
Accessibilitylanguage metadata, translated names, errors, and announcements
Resource validationmissing keys, extra keys, and mismatched placeholders

A pseudo-locale can expand and decorate text to expose hardcoded strings and layout assumptions before real translations arrive.

Save → [Šàṽë-----]

14. Common Mistakes​

MistakeBetter approach
Hardcoding user-visible strings in componentsResolve messages through translation keys
Treating localization as translation onlyInclude formats, plural rules, direction, content, and cultural conventions
Concatenating translated fragmentsTranslate complete messages with interpolation
Assuming English plural rulesUse locale-aware plural selection
Using the browser language without validationMatch it against supported locales and provide a default
Loading every language at startupLazy-load locale and feature resources when scale requires it
Forgetting <html lang> and dirUpdate both when the active locale changes
Using left/right CSS everywherePrefer logical layout properties
Using text as the translation key everywherePrefer stable semantic keys for long-lived applications
Letting missing keys fail silentlyMonitor them and fail appropriate development or CI checks

15. System Design Checklist​

When designing multi-language support, decide:

  • Which locales are supported?
  • Where does the user's preference come from?
  • Is the locale stored in the account, device, URL, or all three?
  • What is the default and fallback chain?
  • Are translations bundled or loaded on demand?
  • How are messages divided into namespaces?
  • How are dates, money, units, and plural forms formatted?
  • Does the interface support RTL and text expansion?
  • How do translators receive context and deliver updates?
  • How are missing keys and incomplete locales detected?
  • Do public pages need localized URLs and metadata?

Official References​


Summary​

Multi-language support separates meaning from presentation so one application can adapt its messages, formats, and layout to each user's locale.


Think of localization as a rendering pipeline:

Meaningful key
+ active locale
+ dynamic values
+ regional formatting rules
+ writing direction
↓
Localized user experience

The goal is not merely to replace English words. It is to make the complete experience feel natural and usable in every supported locale.