next-i18next如何实现开发与生产环境翻译更新无需重启服务
问题核心原因
- Next.js服务端(SSR/SSG)场景下,next-i18next默认会把首次加载的翻译资源缓存到Node.js进程内存,默认不会主动重新拉取,必须重启进程才能清空内存
- 当前配置里的
expirationTime参数仅对浏览器侧的i18next缓存生效,没有覆盖服务端缓存逻辑 - 配置里写了
mode: 'no-cors',该模式下前端无法读取接口返回的JSON内容,实际一直走本地缓存,也是更新不生效的核心诱因 - 开发环境没有开启预渲染重载配置,生产环境没有提供缓存刷新入口
全环境适配解决方案
1. 修正next-i18next基础配置
修改项目根目录的next-i18next.config.js,替换为如下配置,注意把url替换为你实际的翻译服务地址:
const HttpBackend = require('i18next-http-backend') const ChainedBackend = require('i18next-chained-backend') const url = process.env.NEXT_PUBLIC_TRANSLATION_API_URL module.exports = { debug: process.env.NODE_ENV === 'development', backend: { backends: [HttpBackend], backendOptions: [ { loadPath: `${url}/locales/{{lng}}/{{ns}}.json`, crossDomain: true, requestOptions: { mode: 'cors', cache: 'no-store', }, expirationTime: process.env.NODE_ENV === 'development' ? 0 : 60 * 1000, }, ], }, serializeConfig: false, use: [ChainedBackend], i18n: { defaultNS: 'common', defaultLocale: 'en', locales: ['en'], ns: ['common'], reloadOnPrerender: process.env.NODE_ENV === 'development', }, cache: { read: () => null, save: () => {}, }, }
注意:需要给你的翻译资源服务配置CORS跨域头,允许Next.js服务域名访问,否则cors模式下会请求失败。
2. 开发环境热更新配置
如果是Pages Router项目,修改pages/_app.js,加入开发环境轮询重载逻辑,无需刷新页面就能同步最新翻译:
import { appWithTranslation, useTranslation } from 'next-i18next' import { useEffect } from 'react' function MyApp({ Component, pageProps }) { const { i18n } = useTranslation() useEffect(() => { if (process.env.NODE_ENV !== 'development') return const timer = setInterval(() => { i18n.reloadResources() }, 30 * 1000) return () => clearInterval(timer) }, [i18n]) return <Component {...pageProps} /> } export default appWithTranslation(MyApp)
如果是Next.js 13+ App Router项目,在对应语言段的layout文件中加入动态渲染配置,避免构建时静态缓存翻译内容:
// app/[lng]/layout.js export const dynamic = 'force-dynamic'
开发环境下配置完成后,修改翻译内容无需重启dev服务,最多等待30秒即可自动同步,触发热更新时会立刻拉取最新内容。
3. 生产环境无重启更新实现
生产环境采用「过期兜底+主动触发」结合的方案,兼顾性能和更新即时性:
- 兜底逻辑:配置里的
expirationTime设为60秒,用户访问时最多1分钟就会自动拉取最新翻译,不需要重启服务 - 即时更新:新增内部API路由,在翻译内容推送完成后主动触发全量重载,实现秒级生效。新增
pages/api/reload-translations.js文件:
import { i18n } from 'next-i18next' export default async function handler(req, res) { // 替换为自己的内部鉴权逻辑,避免接口被恶意调用 if (req.headers['x-internal-token'] !== process.env.INTERNAL_RELOAD_TOKEN) { return res.status(403).json({ message: 'permission denied' }) } try { await i18n.reloadResources() return res.status(200).json({ message: 'reload success' }) } catch (err) { return res.status(500).json({ message: 'reload failed', error: err.message }) } }
每次翻译内容推送完成后,向该接口发起带鉴权头的POST/GET请求,即可立刻清空服务端和客户端缓存,加载最新翻译内容,全程不需要重启Next.js生产进程。
验证标准
- 开发环境:修改翻译接口返回内容,无需重启
next dev进程,最多30秒页面自动展示新文案 - 生产环境:修改翻译内容后,要么等待1分钟缓存自动过期,要么调用重载接口,刷新页面即可看到新文案,
next start进程全程不需要重启
内容的提问来源于stack exchange,提问作者Swapnil Soni
相关产品推荐
相关产品推荐

