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

Next.js搭配next-i18next时GetStaticProps的revalidate失效

问题描述

使用next-i18next提供的serverSideTranslations方法时,Next.js ISR(增量静态再生成)的revalidate机制无法正常运行,相关复现代码如下。
新用户注册时,系统会为每种支持的语言生成对应的静态页面,支持的语言包括:da(默认语言)、en、sv、de。
项目部署在Vercel平台时,构建阶段已经预生成的页面可以正常运行,下方代码无异常;但新用户注册后,对应页面无法触发重新验证,会抛出500内部服务器错误,提示页面未生成。
具体问题位置可参考代码注释:

export async function getStaticPaths({ locales }) {
  const { data: profiles, error } = await supabase.from("profiles").select("*");
  console.log(locales);

  const paths = profiles
    .map((profile) =>
      locales.map((locale) => ({
        params: { profileName: profile.username },
        locale, // 在此处传入locale
      }))
    )
    .flat();

  console.log(paths);
  return { paths, fallback: "blocking" };
}

export async function getStaticProps({ params, locale }) {
  const { data: profiles, error } = await supabase
    .from("profiles")
    .select("*")
    .eq("username", params.profileName)
    .single();

  return {
    props: {
      profiles,
      ...(await serverSideTranslations(locale, ["Profil"])), // 移除该行时所有功能正常,添加该行后GetStaticPaths和GetStaticProps运行异常
    },
    revalidate: 30,
  };
}
问题根因

该问题和revalidate本身逻辑无关,是serverSideTranslations在ISR动态生成页面的Serverless运行时环境中执行抛错,直接中断了静态页面生成流程,最终返回500错误,常见触发原因有两个:

  • next-i18next的翻译文件路径配置使用了相对路径,Vercel部署时Serverless Function的工作目录和本地开发环境不一致,运行时找不到对应语言的翻译文件直接抛错
  • 首次访问未预生成的多语言路径时,偶发locale参数取值异常(比如取到undefined),serverSideTranslations接收到非法locale参数直接抛出异常
解决方案
  • 对齐Next.js和next-i18next的i18n配置,确保两边声明的默认语言、支持语言列表完全一致,避免locale参数匹配异常:
// next.config.js
module.exports = {
  i18n: {
    defaultLocale: 'da',
    locales: ['da', 'en', 'sv', 'de'],
  },
}
  • 修正next-i18next配置中的翻译文件路径,使用Node.js绝对路径指向翻译文件目录,保证Vercel运行时可以正确读取文件:
// next-i18next.config.js
const path = require('path')

module.exports = {
  i18n: {
    defaultLocale: 'da',
    locales: ['da', 'en', 'sv', 'de'],
  },
  localePath: path.resolve('./public/locales'),
}
  • 给getStaticProps增加错误兜底和参数校验,避免未捕获异常中断ISR流程:
export async function getStaticProps({ params, locale }) {
  try {
    const { data: profiles, error } = await supabase
      .from("profiles")
      .select("*")
      .eq("username", params.profileName)
      .single();

    // 数据查询异常时直接返回404,避免后续逻辑执行出错
    if (error || !profiles) {
      return { notFound: true, revalidate: 30 }
    }

    // 兜底locale取值,避免传入非法参数
    const activeLocale = locale ?? 'da'
    const pageTranslations = await serverSideTranslations(activeLocale, ["Profil"])

    return {
      props: {
        profiles,
        ...pageTranslations,
      },
      revalidate: 30,
    };
  } catch (err) {
    console.error('Page generate error:', err)
    // 运行时出错时设置短重试间隔,避免持续返回500
    return {
      notFound: true,
      revalidate: 10
    }
  }
}

注意:serverSideTranslations仅适配Pages Router,若使用App Router请勿调用该方法,需要手动初始化i18n实例加载翻译资源。


内容的提问来源于stack exchange,提问作者Charlie Østergaard

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:54:52