Next.js 14.2.12集成i18n遇TypeError错误求助
解决Next.js 14 + react-i18next 国际化 TypeError 问题
你遇到的TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function错误,核心原因是服务端组件(RSC)中不能使用React Context——react-i18next的I18nextProvider依赖Context实现,而你的RootLayout是默认的服务端组件,直接引入会触发错误。
以下是针对性的修复方案:
1. 将I18nextProvider封装为客户端组件
在src/app目录下新建Providers.tsx,明确标记为客户端组件:
'use client'; import { I18nextProvider } from 'react-i18next'; import i18next from '@/../i18n'; export default function Providers({ children }: { children: React.ReactNode }) { return <I18nextProvider i18n={i18next}>{children}</I18nextProvider>; }
2. 修改RootLayout,避免在服务端组件中直接使用Context
更新src/app/[locale]/layout.tsx,将I18nextProvider替换为上面的客户端Providers组件,同时确保<html>标签在Provider外部(服务端渲染的根标签不能被客户端组件包裹):
import { headers } from 'next/headers'; import { Suspense } from 'react'; import Header from '@/components/header/HeaderComponent'; import Footer from '@/components/footer/FooterComponent'; import './globals.css'; import { Spinner } from "react-bootstrap"; import Providers from './Providers'; // 导入客户端Providers export const metadata = { title: 'Some title', description: 'Some desc', }; export default function RootLayout({ children }: { children: React.ReactNode }) { const requestHeaders = headers(); const locale = requestHeaders.get('accept-language')?.split(',')[0].slice(0, 2) || 'va'; return ( <html lang={locale}> <body> <Providers> {/* 用客户端Providers包裹内容 */} <Suspense fallback={<Spinner />}> <Header /> <div style={{ width: '80%', minHeight: '60vh', margin: '0 auto' }}> {children} </div> <Footer /> </Suspense> </Providers> </body> </html> ); }
3. 修正i18n.ts的资源配置错误
你的i18n.ts中把瓦伦西亚语的key写成了ca,但实际配置的locale是va,导致语言切换失效,修正如下:
import i18next from 'i18next'; import { initReactI18next } from 'react-i18next'; import esTranslations from './public/locales/es/common.json'; import vaTranslations from './public/locales/va/common.json'; i18next .use(initReactI18next) .init({ lng: 'va', fallbackLng: 'va', resources: { es: { translation: esTranslations, }, va: { // 从ca改为va,匹配配置的locale translation: vaTranslations, }, }, interpolation: { escapeValue: false, }, }); export default i18next;
4. 修复Middleware的匹配规则
当前middleware的matcher只匹配js/ts文件,无法处理页面路由,导致语言cookie无法正确设置,更新为:
import { NextResponse } from "next/server"; export function middleware(request) { const locale = request.headers.get('accept-language')?.split(',')[0].slice(0, 2) || 'va'; const response = NextResponse.next(); response.cookies.set('NEXT_LOCALE', locale); return response; } export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'] // 匹配所有非静态资源路由 }
5. 组件使用国际化的注意事项
所有需要使用useTranslation或Trans组件的组件,都需要添加'use client'指令,因为这些API依赖客户端Context:
'use client'; import { useTranslation } from 'react-i18next'; export default function HeaderComponent() { const { t } = useTranslation(); return <header>{t('header.title')}</header>; }
内容的提问来源于stack exchange,提问作者StzEZ
相关产品推荐
相关产品推荐

