Skip to main content

概述

使用 next-intl 支持 12 种语言。

支持语言

代码语言
en-USEnglish
zh-CN简体中文
zh-TW繁體中文
ja-JP日本語
ko-KR한국어
de-DEDeutsch
fr-FRFrançais
es-ESEspañol
pt-PTPortuguês
it-ITItaliano
ms-MYBahasa Melayu
ru-RUРусский

目录结构

messages
en-US.json
zh-CN.json
ja-JP.json
...

消息格式

// messages/en-US.json
{
  "meta": {
    "title": "Kira",
    "description": "Kira your photo.",
    "auth_title": "Sign in to Kira",
    "gallery_title": "Kira Gallery"
  },
  "home": {
    "get_started": "Get Started",
    "slogan": "Kira your photo",
    "sign_in": "Sign In",
    "gallery": "Gallery"
  },
  "tool": {
    "export": "Export",
    "crop": "Crop",
    "eraser": "Eraser",
    "upscale": "Upscale",
    "filter": "Filter",
    "adjust": "Adjust"
  },
  "artboard": {
    "layers": "Layers",
    "zoom_in": "Zoom In",
    "zoom_out": "Zoom Out",
    "fill": "Fill",
    "opacity": "Opacity"
  },
  "user": {
    "edit_profile": "Edit Profile",
    "threads": "Thread",
    "gallery": "Gallery",
    "liked": "Liked"
  },
  "error": {
    "session_expired": "Session expired",
    "failed_to_fetch": "Failed to fetch",
    "insufficient_credits": "Insufficient credits. Please upgrade your plan."
  },
  "setting": {
    "settings": "Settings",
    "account": "Account",
    "language": "Language",
    "appearance": "Appearance",
    "logout": "Logout"
  },
  "feed": {
    "prompt": "Prompt",
    "style": "Style",
    "rewind": "Rewind"
  },
  "generator": { ... },
  "guide": { ... },
  "gallery": { ... },
  "billing": { ... }
}
顶层命名空间包括 metahomegeneratorartboardusererror 等。不存在顶层 toolbar 命名空间。

使用方式

import { useTranslations } from 'next-intl';

function ToolBar() {
  const t = useTranslations('tool');

  return (
    <div>
      <Button>{t('filter')}</Button>
      <Button>{t('adjust')}</Button>
    </div>
  );
}

配置

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

export default getRequestConfig(async () => {
  const locale = await getUserLocale();
  return {
    locale,
    messages: (await import(`../messages/${locale}.json`)).default,
  };
});

Locale 解析策略

getUserLocale() 按以下优先级确定当前语言:
  1. x-locale 请求头 — 由中间件 (proxy.ts) 从 URL 中的 [locale] 前缀解析并设置
  2. NEXT_LOCALE cookie — 用户手动切换语言后存储的偏好
  3. Accept-Language 请求头 — 浏览器语言偏好
  4. 回退到 en-US — 默认语言

最佳实践

  1. 使用命名空间组织翻译 key
  2. 保持 key 简短且语义化
  3. 所有语言文件结构保持一致