Internationalization
"Our game's comment section is blowing up!" came the urgent message in the creative team's QQ group.
You open the player feedback panel to see a sea of red alerts:
- Japanese player Yamamoto: "中国語が読めない!" (Can't read Chinese!)
- British player Tom: "Why is there no English version? I'm crying!"
- French player Luc: "Où est la version française?" (Where is the French version?)
- German player Hans: "Kann man die Sprache ändern?" (Can the language be changed?)
As the creator, you know you must immediately solve this language barrier problem! This is where i18next comes to the rescue! It's a powerful internationalization framework that can help you easily implement multilingual support.
Installation
npm install i18next
Info
It is recommended to implement localized configurations in client-side scripts rather than directly integrating them into server-side scripts. This architecture design can better meet the personalized needs of different users, while following the best practices for front-end processing of user specific configurations.
Basic Configuration
// i18n.ts
import i18n from "i18next";
// Initialization configuration
i18n.init({
lng: "en", // Default language
fallbackLng: "en", // Fallback language
debug: false, // Should be false in production
resources: {
en: {
translation: {
// English translations
welcome: "Welcome!",
greeting: "Hello, {{name}}!",
buttons: {
submit: "Submit",
cancel: "Cancel",
},
},
},
zh: {
translation: {
// Chinese translations
welcome: "欢迎!",
greeting: "你好,{{name}}!",
buttons: {
submit: "提交",
cancel: "取消",
},
},
},
},
});
export default i18n;
Core API Usage
1. Basic Translation
import i18n from "./i18n";
// Simple translation
console.log(i18n.t("welcome")); // Output: "Welcome!" or "欢迎!"
// With interpolation
console.log(i18n.t("greeting", { name: "Alice" })); // "Hello, Alice!" or "你好,Alice!"
// Nested keys
console.log(i18n.t("buttons.submit")); // "Submit" or "提交"
2. Language Switching
// Get current language
console.log(i18n.language); // Output current language code
// Change language
i18n.changeLanguage("zh").then(() => {
console.log("Language switched to Chinese");
});
// Listen for language changes
i18n.on("languageChanged", (lng) => {
console.log(`Language changed to: ${lng}`);
});
3. Pluralization
// Configure plural rules
i18n.init({
// ...other configurations
resources: {
en: {
translation: {
itemCount: "{{count}} item",
itemCount_plural: "{{count}} items",
},
},
zh: {
translation: {
itemCount: "{{count}} 个项目",
},
},
},
});
// Usage
console.log(i18n.t("itemCount", { count: 1 })); // "1 item" or "1 个项目"
console.log(i18n.t("itemCount", { count: 5 })); // "5 items" or "5 个项目"
Multilingual Configuration Files
MyGame/
├── i18n/
│ ├── config.ts # i18n initialization config file
│ └── locales/ # Multilingual resources directory
│ ├── en/ # English language pack
│ │ ├── common.json # Common translations
│ │ └── home.json # Homepage-related translations
│ └── zh/ # Chinese language pack
│ ├── common.json # Common translations
│ └── home.json # Homepage-related translations
1. Create JSON Translation Files
English Translation File Example (en/common.json
)
{
"welcome": "Welcome to our application!",
"greeting": "Hello, {{name}}!",
"buttons": {
"submit": "Submit",
"cancel": "Cancel"
},
"itemCount": "{{count}} item",
"itemCount_plural": "{{count}} items"
}
Chinese Translation File Example (zh/common.json
)
{
"welcome": "欢迎使用我们的应用!",
"greeting": "你好,{{name}}!",
"buttons": {
"submit": "提交",
"cancel": "取消"
},
"itemCount": "{{count}} 个项目"
}
zh/home.json
and en/home.json
files are similar and not shown here.
2. Load JSON Configuration
Create i18n/config.ts
configuration file:
import i18n from "i18next";
import zhCNcommon from "./locales/common.json";
import enCommon from "./locales/common.json";
import zhCNhome from "./locales/home.json";
import enHome from "./locales/home.json";
i18n.init({
lng: "en", // Default language set to English
fallbackLng: "en", // Fallback language is also English
supportedLngs: ["en", "zh-CN"], // Supported languages list
resources: {
// Translation resources
en: {
// English resources
translation: enHome, // Default namespace translations
common: enCommon, // 'common' namespace translations
},
"zh-CN": {
// Simplified Chinese resources
translation: zhCNhome, // Default namespace translations
common: zhCNcommon, // 'common' namespace translations
},
},
});
export default i18n;
Usage:
console.log(i18n.t("welcome")); // Outputs welcome from default namespace
console.log(i18n.t("common:welcome")); // Outputs welcome from common namespace
TypeScript Type Support
Create i18n.d.ts
file for enhanced types:
// i18n.d.ts
import "i18next";
import enTranslation from "../locales/en/home.json";
import enCommon from "../locales/en/common.json";
// ...other imports
declare module "i18next" {
interface CustomTypeOptions {
defaultNS: "translation";
resources: {
translation: typeof enTranslation;
common: typeof enCommon;
};
}
}
Summary
Advantages of using pure i18next package in TypeScript client:
- Lightweight: No dependency on other frameworks
- Powerful Features: Supports plurals, interpolation, context, and other advanced features
- Type Safety: Full TypeScript support
- Flexible Extensibility: Plugins can be added as needed
Advantages of configuring i18next with JSON:
- Separation of Concerns: Translation text is separated from code logic
- Easy Maintenance: Non-technical staff can edit translation files
- Version Control Friendly: JSON files are easy to manage in version control and collaborate on
With this configuration approach, you can easily manage internationalization needs for large applications while maintaining clean and maintainable code.