如何将国际化(i18n)字典传入Next.js App Router的Error.js路由?
方案:在Next.js App Router中为客户端Error.js集成服务端i18n字典
1. 通过服务端布局传递i18n字典
在语言专属的服务端layout组件中,先获取用户偏好语言,加载对应字典,再通过React上下文将字典注入到整个路由分支,让客户端的Error.js能直接读取。
示例代码:
app/[lang]/layout.js(服务端组件)
import { getDictionary } from '@/lib/i18n'; import { I18nContext } from '@/lib/i18n/context'; export async function generateStaticParams() { return [{ lang: 'en' }, { lang: 'zh-CN' }]; } export default async function LanguageLayout({ children, params }) { // 服务端加载对应语言的字典 const dictionary = await getDictionary(params.lang); return ( <div lang={params.lang}> {/* 用上下文包裹所有子组件,包括Error.js */} <I18nContext.Provider value={dictionary}> {children} </I18nContext.Provider> </div> ); }
2. 创建i18n上下文(客户端兼容)
单独创建一个带"use client"标记的上下文文件,让客户端组件能通过钩子读取服务端注入的字典:
lib/i18n/context.js
'use client'; import { createContext, useContext } from 'react'; export const I18nContext = createContext(null); export function useI18n() { const context = useContext(I18nContext); if (!context) { throw new Error('useI18n必须在I18nContext.Provider内部使用'); } return context; }
3. 在客户端Error.js中使用字典
Error.js保持"use client"指令,通过自定义钩子获取字典并渲染多语言错误信息:
app/[lang]/Error.js
'use client'; import { useI18n } from '@/lib/i18n/context'; export default function Error({ error, reset }) { const dict = useI18n(); return ( <div className="error-container"> <h1>{dict.error.pageTitle}</h1> <p>{dict.error.description}</p> <button onClick={() => reset()}>{dict.error.retryBtn}</button> </div> ); }
4. 服务端字典加载逻辑
实现字典加载函数,根据语言参数动态导入对应本地化文件:
lib/i18n/index.js
export async function getDictionary(lang) { // 动态导入对应语言的JSON字典,Next.js会自动缓存该请求 const dictModule = await import(`../dictionaries/${lang}.json`); return dictModule.default; }
关键注意点
- 若语言检测依赖Cookie或请求头,可在layout中通过
headers()函数获取对应值,再加载匹配的字典。 - 上下文必须标记"use client",因为客户端组件无法直接使用服务端组件的上下文。
- 该方案避免了客户端重复请求字典,所有本地化数据由服务端一次性注入。
内容的提问来源于stack exchange,提问作者JSMarrocco
相关产品推荐
相关产品推荐

