返回 Skill 列表
extension
分类: 开发与工程无需 API Key

i18n

国际化和本地化。i18next(React, Node.js),next-intl,vue-i18n,ICU消息格式,复数形式,日期/数字格式化,以及RTL支持。使用场景:当用户提到“i18n”,“国际化”,“本地化”,“l10n”,“i18next”,“翻译”,“next-intl”,“vue-i18n”,“ICU格式”,“RTL”时。不应用于:字符编码 - 一般编程;货币/支付格式化 - 使用`stripe`

person作者: jakexiaohubgithub

Internationalization (i18n)

i18next (React — recommended)

// i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    ns: ['common', 'auth'],
    defaultNS: 'common',
    interpolation: { escapeValue: false },
  });

export default i18n;
// Usage in components
import { useTranslation } from 'react-i18next';

function Welcome() {
  const { t } = useTranslation();

  return (
    <>
      <h1>{t('welcome', { name: 'John' })}</h1>
      <p>{t('items_count', { count: 5 })}</p>
    </>
  );
}

Translation Files

// locales/en/common.json
{
  "welcome": "Welcome, {{name}}!",
  "items_count_one": "{{count}} item",
  "items_count_other": "{{count}} items"
}

// locales/it/common.json
{
  "welcome": "Benvenuto, {{name}}!",
  "items_count_one": "{{count}} elemento",
  "items_count_other": "{{count}} elementi"
}

next-intl (Next.js)

// i18n/request.ts
import { getRequestConfig } from 'next-intl/server';

export default getRequestConfig(async ({ locale }) => ({
  messages: (await import(`../messages/${locale}.json`)).default,
}));
import { useTranslations } from 'next-intl';

function Page() {
  const t = useTranslations('HomePage');
  return <h1>{t('title')}</h1>;
}

Date & Number Formatting

// Use Intl API (built-in, no library needed)
const dateFormatter = new Intl.DateTimeFormat('de-DE', {
  year: 'numeric', month: 'long', day: 'numeric',
});
dateFormatter.format(new Date()); // "5. Marz 2026"

const currencyFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency', currency: 'USD',
});
currencyFormatter.format(42.5); // "$42.50"

// Relative time
const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });
rtf.format(-1, 'day'); // "yesterday"

ICU Message Format

{
  "greeting": "{gender, select, male {Mr.} female {Ms.} other {Mx.}} {name}",
  "notifications": "{count, plural, =0 {No notifications} one {# notification} other {# notifications}}"
}

Translation File Structure

locales/
├── en/
│   ├── common.json      # Shared strings
│   ├── auth.json         # Auth-specific
│   └── errors.json       # Error messages
├── it/
│   ├── common.json
│   ├── auth.json
│   └── errors.json

Anti-Patterns

| Anti-Pattern | Fix | |--------------|-----| | Hardcoded strings in UI | Extract all user-facing text to translation files | | String concatenation for sentences | Use interpolation ({{name}}) or ICU format | | Manual pluralization logic | Use built-in plural rules (_one, _other) | | Date formatting with string manipulation | Use Intl.DateTimeFormat | | No fallback language | Always set fallbackLng | | Giant single translation file | Split by namespace (common, auth, errors) |

Production Checklist

  • [ ] All user-facing strings externalized
  • [ ] Pluralization rules for all supported languages
  • [ ] Date/number formatting with Intl API
  • [ ] RTL layout support (if applicable)
  • [ ] Language detection (browser, user preference)
  • [ ] Translation workflow with translators
  • [ ] Missing key detection in CI