如何在Next.js 13+中配置i18next适配服务端与客户端组件
Next.js 13 App目录 + i18next 国际化配置方案
1. 安装依赖
npm install next-i18next i18next react-i18next # 或使用yarn yarn add next-i18next i18next react-i18next
2. 规范翻译文件结构
确保翻译文件存放在public/locales目录下,结构如下:
public/ locales/ en/ translation.json zh/ translation.json
示例翻译内容:en/translation.json:
{ "welcome": "Welcome to Next.js 13", "description": "Internationalization with i18next" }
zh/translation.json:
{ "welcome": "欢迎来到Next.js 13", "description": "使用i18next实现国际化" }
3. 核心配置文件
3.1 配置next-i18next.config.js
在项目根目录创建该文件:
module.exports = { i18n: { defaultLocale: 'en', locales: ['en', 'zh'], localeDetection: false, // 按需开启自动语言检测 }, localePath: './public/locales', // 指向翻译文件存放目录 reloadOnPrerender: true, // 开发模式下支持翻译文件热更新 }
3.2 同步Next.js配置
修改next.config.js,引入国际化配置:
const { i18n } = require('./next-i18next.config') /** @type {import('next').NextConfig} */ const nextConfig = { i18n, // 其他Next.js自定义配置 } module.exports = nextConfig
4. 解决服务端组件调用useTranslation报错
服务端组件无法直接使用客户端Hook(useTranslation属于客户端Hook),提供两种解决方案:
方案1:将组件标记为客户端组件
在组件顶部添加'use client'指令,即可正常使用useTranslation:
'use client' import { useTranslation } from 'react-i18next' export default function ClientComponent() { const { t } = useTranslation() return <h1>{t('welcome')}</h1> }
方案2:服务端组件直接初始化i18next实例翻译
创建服务端翻译工具函数app/utils/server-translate.ts:
import i18next from 'i18next' import { initReactI18next } from 'react-i18next' import enTranslation from '../../public/locales/en/translation.json' import zhTranslation from '../../public/locales/zh/translation.json' const initI18next = async (locale: string) => { await i18next.use(initReactI18next).init({ resources: { en: { translation: enTranslation }, zh: { translation: zhTranslation }, }, lng: locale, fallbackLng: 'en', interpolation: { escapeValue: false }, }) return i18next } export const getServerTranslation = async (locale: string) => { const i18n = await initI18next(locale) return { t: i18n.t } }
在服务端组件中调用:
import { getServerTranslation } from './utils/server-translate' import { headers } from 'next/headers' export default async function ServerComponent() { const headersList = headers() // 从请求头或路由参数获取当前语言 const locale = headersList.get('x-next-locale') || 'en' const { t } = await getServerTranslation(locale) return <h1>{t('welcome')}</h1> }
5. 解决客户端组件找不到translation.json问题
- 确认
next-i18next.config.js中的localePath配置为./public/locales,且翻译文件确实存在于该目录 - 开发模式下修改翻译文件后,若未自动更新,可重启开发服务器(开启
reloadOnPrerender: true可实现热更新)
6. 替代v12的getStaticProps实现多语言静态生成
在App目录下,使用generateStaticParams生成多语言路由参数,结合国际化配置:
示例app/[lang]/page.tsx:
import { getServerTranslation } from '../utils/server-translate' // 生成静态路由参数 export async function generateStaticParams() { return [ { lang: 'en' }, { lang: 'zh' }, ] } export default async function Page({ params }: { params: { lang: string } }) { const { t } = await getServerTranslation(params.lang) return ( <div> <h1>{t('welcome')}</h1> <p>{t('description')}</p> </div> ) }
上述代码会静态生成/en和/zh两个语言路由页面,替代v12中getStaticProps的作用。
可选:添加中间件处理路由重定向(middleware.ts)
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname // 检查路径是否已有语言前缀 const hasLocale = ['/en', '/zh'].some(locale => pathname.startsWith(locale)) if (!hasLocale) { // 默认重定向到英文路由 return NextResponse.redirect(new URL('/en' + pathname, request.url)) } } export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], }
内容的提问来源于stack exchange,提问作者Aleksandar Hristov
相关产品推荐
相关产品推荐

