如何解决Inertia SSR结合i18next时的react-i18next初始化报错
解决Inertia SSR下react-i18next初始化及Ziggy路由参数问题
1. 重构i18n配置,适配SSR环境
服务端渲染需要为每个请求创建独立的i18n实例,不能使用客户端的单例配置,同时要避免在服务端加载浏览器专属插件(如i18next-http-backend、i18next-browser-languagedetector)。
修改utils/i18n.js为工厂函数模式:
import i18n from "i18next"; import { initReactI18next } from "react-i18next"; import Backend from "i18next-http-backend"; import LanguageDetector from "i18next-browser-languagedetector"; export function createI18nInstance(locale = "en") { const instance = i18n.createInstance(); const plugins = [initReactI18next]; // 仅客户端加载浏览器专属插件 if (typeof window !== "undefined") { plugins.push(Backend, LanguageDetector); } instance.use(...plugins).init({ lng: locale, // 服务端渲染时传入当前请求的locale detection: { order: ["path", "htmlTag"], }, fallbackLng: "en", interpolation: { escapeValue: false, }, // 服务端预加载翻译文件(需提前将翻译文件放在locales目录) resources: typeof window === "undefined" ? { en: { translation: require("../locales/en.json") }, zh: { translation: require("../locales/zh.json") }, // 按需添加其他语言 } : undefined, }); return instance; } // 客户端默认导出实例 if (typeof window !== "undefined") { export default createI18nInstance(); }
2. 修改客户端入口(app.jsx)
用I18nextProvider包裹根组件,确保客户端i18n实例正确注入:
import React from 'react'; import ReactDOM from 'react-dom/client'; import { createInertiaApp } from '@inertiajs/react'; import { createI18nInstance } from './utils/i18n'; import { I18nextProvider } from 'react-i18next'; const i18n = createI18nInstance(); createInertiaApp({ resolve: (name) => require(`./Pages/${name}`), setup({ el, App, props }) { ReactDOM.createRoot(el).render( <I18nextProvider i18n={i18n}> <App {...props} /> </I18nextProvider> ); }, });
3. 修改服务端入口(ssr.jsx)
在服务端渲染时,根据请求locale创建i18n实例,并注入到组件树,同时配置Ziggy默认参数:
import React from 'react'; import { renderToString } from 'react-dom/server'; import { createInertiaApp } from '@inertiajs/react'; import { createI18nInstance } from './utils/i18n'; import { I18nextProvider } from 'react-i18next'; import { Ziggy } from './ziggy'; export default function render(page) { return createInertiaApp({ page, render: renderToString, resolve: (name) => require(`./Pages/${name}`), setup({ App, props }) { // 从Inertia共享数据中获取locale(需后端传递) const locale = page.props.locale || 'en'; const i18n = createI18nInstance(locale); // 给Ziggy设置默认locale参数,避免路由报错 Ziggy.defaultParams = { ...Ziggy.defaultParams, locale }; return ( <I18nextProvider i18n={i18n}> <App {...props} /> </I18nextProvider> ); }, }); }
4. 后端传递Locale到Inertia
在Laravel的HandleInertiaRequests中间件中,共享当前请求的locale:
// app/Http/Middleware/HandleInertiaRequests.php public function share(Request $request) { return array_merge(parent::share($request), [ 'locale' => app()->getLocale(), // 其他共享数据 ]); }
5. 优化路由调用方式
避免依赖useTranslation的i18n实例获取locale,直接从Inertia共享props中读取,确保SSR时参数可用:
import { usePage } from '@inertiajs/react'; import { useTranslation } from 'react-i18next'; const { props } = usePage(); const { t } = useTranslation(); // 使用props.locale替代i18n.language route('application.home.index', { locale: props.locale })
内容的提问来源于stack exchange,提问作者Mohammad Morakabati
相关产品推荐
相关产品推荐

