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

Next.js动态路由Vercel部署新应用预览404问题求助

问题分析与解决方案

核心问题原因

你遇到的404本质是静态路径预生成逻辑的局限性:

  • getStaticPaths 是在Vercel构建阶段执行的,只会抓取构建时刻数据库里的旧应用ID生成静态路径
  • 部署后新创建的应用ID不会被自动加入预生成路径列表,即便设置了 fallback: 'blocking',也因为你通过硬编码的生产环境API获取路径(构建时API尚未部署完成,调用失败),导致新ID无法触发增量渲染
  • 手动重新部署会重新执行 getStaticPaths,此时新应用ID已存在于数据库,因此能生成对应的静态页面

另外你配置的 vercel.json 重写规则会把所有请求导向 index.html,完全破坏了Next.js的动态路由机制,这也是问题诱因之一。


解决方案

方案1:改用Supabase直连替代API路由(推荐)

删除构建时调用自身API的逻辑,直接在 getStaticPaths 和 getStaticProps 中用Supabase客户端查询数据库,避免构建阶段API不可用的问题,同时启用增量静态再生(ISR)自动更新页面。

修改后的 [id].js 代码:

import { createClient } from '@supabase/supabase-js';

// 初始化Supabase服务端客户端(用服务端密钥获取全权限)
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,
  process.env.SUPABASE_SERVICE_ROLE_KEY
);

export const getStaticPaths = async () => {
  // 直接从数据库获取所有应用ID
  const { data: applications, error } = await supabase
    .from('applications')
    .select('appid');

  if (error) {
    console.error('获取路径失败:', error);
    return { paths: [], fallback: 'blocking' };
  }

  const paths = applications.map(application => ({
    params: { id: application.appid.toString() }
  }));

  return {
    paths,
    fallback: 'blocking'
  };
};

export async function getStaticProps(context) {
  const appID = context.params.id;

  // 直接从数据库获取对应应用数据
  const { data: application, error } = await supabase
    .from('applications')
    .select('*')
    .eq('appid', appID)
    .single();

  if (error || !application) {
    return { notFound: true };
  }

  return {
    props: { data: application },
    // 启用增量静态再生:每60秒自动重新生成页面,适配新数据
    revalidate: 60
  };
}

方案2:改用服务器端渲染(SSR)

如果对页面实时性要求极高,直接用 getServerSideProps 替代静态生成逻辑,每次请求都实时从数据库拉取数据,彻底规避路径预生成的问题:

import { createClient } from '@supabase/supabase-js';

export async function getServerSideProps(context) {
  const appID = context.params.id;
  const supabase = createClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL,
    process.env.SUPABASE_SERVICE_ROLE_KEY
  );

  const { data: application, error } = await supabase
    .from('applications')
    .select('*')
    .eq('appid', appID)
    .single();

  if (error || !application) {
    return { notFound: true };
  }

  return {
    props: { data: application }
  };
}

注意:使用SSR时不需要写 getStaticPaths

必须执行的配置修正

  1. 删除 vercel.json 中的重写规则,Next.js在Vercel上会自动处理路由,该配置会导致动态路由失效
  2. 确保Vercel后台已正确配置Supabase的环境变量:NEXT_PUBLIC_SUPABASE_URL 和 SUPABASE_SERVICE_ROLE_KEY

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 16:25:21