You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js中i18next构建时未注入翻译文本,运行时才解析问题

解决Next.js + next-i18next静态构建时无法替换翻译键为实际文本的问题

问题场景

我在项目中使用next-i18next实现国际化,但静态构建(SSG)阶段生成的内容里保留了翻译键,直到运行时才解析成实际文本。当前构建输出的内容类似:

<div style="display:absolute">components.atoms.characteristicsPost.averageReadingLast</div>

期望构建时直接输出翻译后的内容:

<div style="display:absolute">12 mins</div>

我的配置与代码如下:

next-18next.config.js

module.exports = {
  i18n: {
    defaultLocale: 'es',
    locales: ['es', 'en'],
    ns: ['common']
  },
};

next.config.js

const { i18n } = require('./next-i18next.config');
const nextConfig = {
 i18n
};
 
module.exports = nextConfig;

[..uri]页面的getStaticProps

export async function getStaticProps({ locale, params }) {
  const ruta = `/${params.uri?.join('/')}`;

  const { page, posts, configuraciones, CabeceraES, PieES, CabeceraEN, PieEN } =
    await getPage(ruta);

  const traductionProps = await serverSideTranslations(locale, ['common']);

  return {
    props: {
      page,
      posts,
      configuraciones,
      CabeceraES,
      PieES,
      CabeceraEN,
      PieEN,
      ...traduccionProps,
    },
    revalidate: 500,
    notFound: !page,
  };
}

解决方案

核心思路

要在静态构建阶段完成翻译,需要在getStaticProps中主动加载对应语言的翻译资源,提前将数据中的翻译键替换为实际翻译文本,而不是依赖客户端的t函数在运行时解析。

具体步骤

  1. 加载对应语言的翻译文件
    在getStaticProps中,根据当前locale加载对应的翻译资源文件(假设翻译文件存放在public/locales/{locale}/common.json):
export async function getStaticProps({ locale, params }) {
  const ruta = `/${params.uri?.join('/')}`;

  const { page, posts, configuraciones, CabeceraES, PieES, CabeceraEN, PieEN } =
    await getPage(ruta);

  // 加载当前locale的common翻译文件
  const translations = require(`../public/locales/${locale}/common.json`);

  // ...后续处理
}
  1. 编写翻译替换函数
    实现一个递归函数,遍历需要翻译的数据(比如page、posts),将其中的翻译键替换为实际文本:
// 递归替换对象中的翻译键
const translateKeys = (data, translations) => {
  if (typeof data === 'string') {
    // 如果是字符串,检查是否是翻译键,存在则替换
    return translations[data] || data;
  }
  if (Array.isArray(data)) {
    return data.map(item => translateKeys(item, translations));
  }
  if (typeof data === 'object' && data !== null) {
    const translatedObj = {};
    for (const key in data) {
      translatedObj[key] = translateKeys(data[key], translations);
    }
    return translatedObj;
  }
  return data;
};
  1. 处理数据并返回
    在返回props之前,对需要翻译的数据进行替换:
export async function getStaticProps({ locale, params }) {
  const ruta = `/${params.uri?.join('/')}`;

  const { page, posts, configuraciones, CabeceraES, PieES, CabeceraEN, PieEN } =
    await getPage(ruta);

  const translations = require(`../public/locales/${locale}/common.json`);
  
  // 翻译需要静态渲染的数据
  const translatedPage = translateKeys(page, translations);
  const translatedPosts = translateKeys(posts, translations);
  const translatedConfiguraciones = translateKeys(configuraciones, translations);

  const traductionProps = await serverSideTranslations(locale, ['common']);

  return {
    props: {
      page: translatedPage,
      posts: translatedPosts,
      configuraciones: translatedConfiguraciones,
      CabeceraES,
      PieES,
      CabeceraEN,
      PieEN,
      ...traduccionProps,
    },
    revalidate: 500,
    notFound: !page,
  };
}
  1. 修改组件渲染逻辑
    组件中不再使用t(key),而是直接使用props中已经翻译好的文本:
// 错误写法(运行时解析)
<div style="display:absolute">{t('components.atoms.characteristicsPost.averageReadingLast')}</div>

// 正确写法(构建时已翻译)
<div style="display:absolute">{page.averageReadingLast}</div>

注意事项

  • 确保翻译文件路径正确,根据你的项目结构调整../public/locales/${locale}/common.json的路径。
  • 如果你的翻译键包含命名空间(ns),需要对应加载对应的命名空间文件。
  • 保留serverSideTranslations,以支持客户端路由切换时的翻译需求。

内容的提问来源于stack exchange,提问作者Eduardo Gil Calvo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 07:15:44