Skip to content

Next.js 国际化 (i18n) 🌍

🎯 概述

国际化(Internationalization,i18n)让你的应用支持多种语言,Next.js 提供了内置的 i18n 路由支持和多种第三方库集成方案。

📦 next-intl (推荐)

安装

bash
npm install next-intl

配置

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

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

// middleware.ts
import createMiddleware from 'next-intl/middleware'

export default createMiddleware({
  locales: ['zh', 'en'],
  defaultLocale: 'zh'
})

export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)']
}

翻译文件

json
// messages/zh.json
{
  "home": {
    "title": "欢迎",
    "description": "这是首页"
  },
  "nav": {
    "home": "首页",
    "about": "关于"
  }
}

// messages/en.json
{
  "home": {
    "title": "Welcome",
    "description": "This is home page"
  },
  "nav": {
    "home": "Home",
    "about": "About"
  }
}

使用翻译

tsx
// app/[locale]/page.tsx
import { useTranslations } from 'next-intl'

export default function Home() {
  const t = useTranslations('home')
  
  return (
    <div>
      <h1>{t('title')}</h1>
      <p>{t('description')}</p>
    </div>
  )
}

🚀 react-i18next

安装

bash
npm install react-i18next i18next

配置

tsx
// lib/i18n.ts
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'

i18n
  .use(initReactI18next)
  .init({
    resources: {
      zh: {
        translation: {
          welcome: '欢迎',
          hello: '你好,{{name}}'
        }
      },
      en: {
        translation: {
          welcome: 'Welcome',
          hello: 'Hello, {{name}}'
        }
      }
    },
    lng: 'zh',
    fallbackLng: 'en',
    interpolation: {
      escapeValue: false
    }
  })

export default i18n

使用

tsx
'use client'

import { useTranslation } from 'react-i18next'

export default function Component() {
  const { t, i18n } = useTranslation()
  
  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('hello', { name: '张三' })}</p>
      <button onClick={() => i18n.changeLanguage('en')}>
        English
      </button>
    </div>
  )
}

📝 语言切换

语言选择器

tsx
'use client'

import { useRouter, usePathname } from 'next/navigation'
import { useLocale } from 'next-intl'

export default function LanguageSwitcher() {
  const router = useRouter()
  const pathname = usePathname()
  const locale = useLocale()
  
  const switchLanguage = (newLocale: string) => {
    const newPathname = pathname.replace(`/${locale}`, `/${newLocale}`)
    router.push(newPathname)
  }
  
  return (
    <select value={locale} onChange={(e) => switchLanguage(e.target.value)}>
      <option value="zh">中文</option>
      <option value="en">English</option>
    </select>
  )
}

📚 最佳实践

1. 组织翻译文件

messages/
  zh/
    common.json
    home.json
    about.json
  en/
    common.json
    home.json
    about.json

2. 类型安全

tsx
// types/i18n.ts
export type Locale = 'zh' | 'en'

export type Messages = typeof import('../messages/zh.json')

3. 动态导入

tsx
export default getRequestConfig(async ({ locale }) => ({
  messages: (await import(`./messages/${locale}.json`)).default
}))

🔗 相关资源


下一步:学习 Next.js 测试