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.json2. 类型安全
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 测试。