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

NextJS可选兜底路由是否会导致重复调用及额外页面生成?

关于NextJS App Router可选兜底路由SSG模式下额外页面与重复调用的问题

项目背景

正在将基于Bloomreach CMS的项目重构为NextJS App Router应用,采用单入口兜底路由结构:

app
- layout.tsx
- [[...route]]
-- page.tsx

当前配置为SSG模式,核心代码如下:

const getPage = cache(
  async ({ requestURL, tags }: { requestURL: string; tags: string[] }) => {
    return await fetchItem(requestURL, tags);
  },
);

export async function generateStaticParams() {
  const pages = (await getWebsitePaths()) ?? [];
  return Array.from(new Set(pages)).map((url) => ({
    route: urlStringToArray(url),
  }));
}

export default async function Page({
  params,
}: { params: { route: string[] }; }) {
  let configuration;
  let commerceConfig;
  let pageModel;
  const route = params.route && params.route.length > 0 ? params.route : [''];

  const isPreview = process.env.NEXT_PUBLIC_IS_PREVIEW === 'true';
  let pathname: string | null = paramCreation(route);

  const requestUrl = pathCheck(pathname, '');
  const tags = [mapCacheTag(pathname)];

  configuration = buildConfiguration(`${pathname}?`);
  pageModel = await getPage({ requestURL: requestUrl, tags });

  if (!pageModel || pageModel.status === 404) {
    notFound();
  }

  commerceConfig = loadCommerceConfig(pageModel);

  return (
    <BrxApp
      configuration={configuration!}
      page={pageModel}
      commerceConfig={commerceConfig!}
    />
  );
}

问题现象

项目可正常构建、启动及导航,但构建时出现7个不在预设路径列表中的额外页面,且存在getPage重复调用的情况。已排查:限制fetch调用、移除middleware、确认fetchItem已缓存。

解答与建议

这不是可选兜底路由的正常行为

额外页面生成与重复调用属于异常情况,可从以下方向排查:

  1. 检查generateStaticParams的输出

    • 确认getWebsitePaths()返回的原始路径是否包含意外内容(如空字符串、测试路径、NextJS默认资源路径),即使做了去重,原始数据的脏数据也会导致额外页面。
    • 在generateStaticParams中添加日志,打印生成的所有路径,定位额外页面的来源:
      export async function generateStaticParams() {
        const pages = (await getWebsitePaths()) ?? [];
        const uniquePages = Array.from(new Set(pages));
        console.log('预渲染路径列表:', uniquePages); // 查看是否包含额外路径
        return uniquePages.map((url) => ({
          route: urlStringToArray(url),
        }));
      }
      
    • 验证urlStringToArray的转换逻辑,确保路径转换一致(如/about转成['about'],根路径转成['']),避免因转换错误生成无效route。
  2. 过滤NextJS默认资源路径

    • NextJS构建时会自动处理/favicon.ico、/robots.txt、/sitemap.xml等默认资源,若未过滤,兜底路由会匹配这些路径生成额外页面。可在generateStaticParams中过滤这类路径:
      const excludePaths = ['/favicon.ico', '/robots.txt', '/sitemap.xml'];
      const uniquePages = Array.from(new Set(pages)).filter(url => !excludePaths.includes(url));
      
  3. 排查重复调用的根源

    • 确认getPage的缓存键是否唯一:检查requestURL和tags是否因路径格式差异(如末尾斜杠/about vs /about/)导致缓存失效,重复触发调用。
    • 统一paramCreation和pathCheck的路径处理逻辑,确保相同路由生成完全一致的pathname和requestUrl(如统一去掉末尾斜杠)。
    • 检查预览模式是否被意外触发:构建时若NEXT_PUBLIC_IS_PREVIEW被设为true,可能会触发额外的预渲染逻辑。
  4. 检查项目内的Link组件

    • NextJS的SSG会自动预渲染Link组件指向的所有路径,即使这些路径不在generateStaticParams的返回列表中。排查项目内是否有Link指向那7个额外页面的路径。
  5. 确认缓存有效性

    • 若使用的是React内置的cache,它仅在同一次请求内生效,跨请求的缓存需依赖NextJS的fetch缓存(默认cache: 'force-cache')或自定义持久化缓存。检查fetchItem中的fetch请求是否配置了正确的缓存模式。

内容的提问来源于stack exchange,提问作者ers020

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 09:32:07