使用next-i18next对接CMS翻译键时getServerSideProps报错求助
使用next-i18next结合CMS翻译键(SSR模式)时出现
._nextI18Next.userConfig.use[0]错误的解决方案 我尝试用next-i18next从CMS获取翻译键,采用SSR模式使用getServerSideProps,但出现._nextI18Next.userConfig.use[0]错误,已经卡了好几天。以下是我的配置文件和页面代码,求排查思路:
我的next-i18next.config.js:
/* eslint-disable @typescript-eslint/no-var-requires */ const i18nextHttpBackend = require('i18next-http-backend') const i18nextBrowserLanguageDetector = require('i18next-browser-languagedetector') const axios = require('axios') module.exports = { i18n: { defaultLocale: 'default', locales: ['default', 'gb', 'fr'] }, use: [i18nextHttpBackend, i18nextBrowserLanguageDetector], debug: true, fallbackLng: 'fr', interpolation: { format: (value, format, lng) => { if (value instanceof Date) { return DateTime.fromJSDate(value).setLocale(lng).toLocaleString(DateTime[format]) } return value } }, backend: { loadPath: lng => { axios.get(`https://my_api_url/${lng}/formatted-transkeys`).then(res => { return JSON.stringify(res.data) }) } }, serializeConfig: false }
我的next.config.js:
/* eslint-disable @typescript-eslint/no-var-requires */ const { i18n } = require('./next-i18next.config') const nextConfig = { distDir: 'dist', reactStrictMode: false, i18n, trailingSlash: true, images: { domains: ['d1m7xnn75ypr6t.cloudfront.net'] } } module.exports = nextConfig
我的index.tsx:
interface i18nProps { locale: string } export const getServerSideProps = async (props: i18nProps) => { const result = await getHomePageData(props.locale) const data = result.data return { props: { data: data, ...(await serverSideTranslations(props.locale, ['search'])) } } } export default Homepage
错误原因分析
backend.loadPath配置完全错误:loadPath的作用是返回一个URL模板字符串,由i18next-http-backend自动发起请求加载翻译,你当前的写法是手动执行axios请求,不仅异步无返回值,还违背了该配置的设计逻辑。- SSR环境误用浏览器语言检测器:
i18next-browser-languagedetector仅适用于浏览器端,直接放在全局use数组中会导致服务端运行异常。 - 未引入依赖模块:
interpolation.format中用到的DateTime没有引入对应模块(如luxon),会引发运行时错误。 serializeConfig: false的潜在问题:该配置会阻止next-i18next序列化配置传递到客户端,导致SSR前后端配置不一致。
解决方案
步骤1:修正next-i18next.config.js
/* eslint-disable @typescript-eslint/no-var-requires */ const i18nextHttpBackend = require('i18next-http-backend'); const axios = require('axios'); const { DateTime } = require('luxon'); // 引入DateTime模块 module.exports = { i18n: { defaultLocale: 'default', locales: ['default', 'gb', 'fr'] }, use: [i18nextHttpBackend], // 仅保留服务端可用的http-backend debug: true, fallbackLng: 'fr', interpolation: { format: (value, format, lng) => { if (value instanceof Date) { return DateTime.fromJSDate(value).setLocale(lng).toLocaleString(DateTime[format]); } return value; } }, backend: { // 返回URL模板,i18next会自动替换{{lng}}为当前语言 loadPath: 'https://my_api_url/{{lng}}/formatted-transkeys', // 若API需要自定义请求逻辑(如加认证头),可通过request选项实现 request: async (options, url, payload, callback) => { try { const res = await axios.get(url); callback(null, res.data); } catch (e) { callback(e, null); } } }, serializeConfig: true // 允许配置序列化,保证前后端一致 };
步骤2:在客户端单独配置语言检测器
在_app.tsx中仅在客户端初始化浏览器语言检测器:
import { appWithTranslation } from 'next-i18next'; import i18nextBrowserLanguageDetector from 'i18next-browser-languagedetector'; import { i18n } from '../next-i18next.config'; // 仅在浏览器环境加载语言检测器 if (typeof window !== 'undefined') { i18n.use(i18nextBrowserLanguageDetector); } function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } export default appWithTranslation(MyApp);
步骤3:优化getServerSideProps类型与逻辑
import { GetServerSideProps } from 'next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; interface HomePageProps { data: any; // 替换为你的实际数据类型 } export const getServerSideProps: GetServerSideProps<HomePageProps> = async ({ locale }) => { const result = await getHomePageData(locale || 'fr'); // 增加locale fallback const data = result.data; return { props: { data, ...(await serverSideTranslations(locale || 'fr', ['search'])) } }; }; export default Homepage;
额外注意事项
- 确保CMS API返回标准的键值对格式JSON翻译文件。
- 若API需要认证,在
backend.request中添加自定义请求头即可,不要修改loadPath。 - 测试SSR时,保证服务器能正常访问CMS API,避免跨域或网络权限问题。
内容的提问来源于stack exchange,提问作者Memphi
相关产品推荐
相关产品推荐

