JavaScript项目中如何处理国际化(i18n)复杂字符串及复数场景?
Hey there! Let's break down your i18n questions one by one—these are super common hurdles when localizing apps, so glad you're asking!
The core idea is to separate your app's logic from translatable text, so translators don't have to wade through code, and you avoid messy string concatenation that breaks localization. Here are my top strategies:
- Split logic and text: Never hardcode conditional logic (like plural rules or gender variations) directly into strings. Let your i18n library handle these rules instead—they’re built to account for weird language quirks (looking at you, Arabic’s 6 plural forms).
- Use placeholders and interpolation: Stick with syntax like
{{variable}}for dynamic values. This lets translators focus on wording without worrying about how variables get inserted, and most libraries support formatting (like number commas or date styles) right in the placeholder. - Leverage built-in plural/gender rules: Don’t write
if (number === 1) { ... }checks yourself. i18n libraries use Unicode’s CLDR data to handle pluralization for every language automatically—so your code stays clean, and translations are accurate for all locales. - Handle rich text safely: If your string needs links, bold text, or components, don’t embed raw HTML. Use your library’s nested syntax (like i18next’s
Transcomponent) to mix text and components safely, avoiding XSS risks and keeping translations flexible. - Extract reusable snippets: Pull common text (like button labels or error messages) into their own translation keys. This avoids duplicate translations and makes it easy to update wording across your app in one place.
Rolling your own plural logic is a trap—you’ll only cover English, and miss edge cases (like 0 apples or languages with more than two plural forms). The best approach is to use i18next (or react-i18next for React apps), a mature library that handles pluralization out of the box. Here’s how to set it up:
Step 1: Install dependencies
For a vanilla JS project:
npm install i18next i18next-http-backend i18next-browser-languagedetector
For React:
npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector
Step 2: Configure i18n
Initialize the library with your translation resources and enable plural support (it’s on by default for most setups):
// i18n.js import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; // Skip this for vanilla JS import Backend from 'i18next-http-backend'; import LanguageDetector from 'i18next-browser-languagedetector'; i18n .use(Backend) // Load translations from JSON files (optional but recommended) .use(LanguageDetector) // Auto-detect user's language .use(initReactI18next) // Only for React .init({ fallbackLng: 'en', interpolation: { escapeValue: false // React handles XSS protection, so disable this }, resources: { en: { translation: { buyApples: { one: "I want to buy {{number}} apple.", other: "I want to buy {{number}} apples." } } } } }); export default i18n;
Step 3: Use the translation in your code
- Vanilla JS:
import i18n from './i18n'; console.log(i18n.t('buyApples', { number: 1 })); // Output: "I want to buy 1 apple." console.log(i18n.t('buyApples', { number: 5 })); // Output: "I want to buy 5 apples." console.log(i18n.t('buyApples', { number: 0 })); // Output: "I want to buy 0 apples." (uses "other" rule for English) - React Component:
import { useTranslation } from 'react-i18next'; function AppleCart() { const { t } = useTranslation(); const appleCount = 3; return <p>{t('buyApples', { number: appleCount })}</p>; }
Why this is optimal:
- Full language support: i18next uses CLDR data to handle plural rules for over 100 languages—no more writing custom logic for each locale.
- Maintainable: Translations are stored in JSON files, so you can update or add new languages without touching code.
- Safe: The library handles XSS protection for interpolated values, so you don’t have to worry about malicious user input.
- Scalable: If you need to add gender variations, rich text, or nested translations later, the library has built-in support for all of that.
内容的提问来源于stack exchange,提问作者Anton Huz

