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

NextJS按需生成商品动态路由问题求助

Next.js 商品动态路由解决方案(无需全量预渲染)

问题描述

我正在使用NextJS为一个当前包含数千个商品且数量将大幅增长的数据库搭建前端,现有的site/products/路由运行正常。我希望添加一个查看单个商品的路由,例如site/products/{sku},创建动态路由组件后却持续出现404错误。经调研得知,动态路由需借助getStaticPaths和getStaticProps预渲染所有页面,但我不想每次执行npm run build时生成数千个页面,希望通过URL中的sku值调用API,在客户端或服务端动态生成页面并返回渲染后的HTML,请问该如何实现?我的思路是否有误?

可行方案

1. 增量静态再生(ISR)—— 推荐用于非实时数据

这种方式不需要在构建时预渲染所有页面,首次请求未生成的商品页面时,服务端会自动生成静态页面并缓存,后续请求直接返回缓存内容,还能按需更新缓存。

  • 路由文件命名:Pages Router用pages/products/[sku].js;App Router用app/products/[sku]/page.js
  • 核心配置:getStaticPaths中设置fallback: 'blocking',getStaticProps添加revalidate参数控制缓存更新时间

Pages Router 示例代码:

export async function getStaticPaths() {
  return {
    paths: [], // 构建时不预渲染任何商品页面
    fallback: 'blocking', // 首次请求未预渲染路径时,服务端生成页面
  };
}

export async function getStaticProps({ params }) {
  // 通过sku调用API获取商品数据
  const res = await fetch(`https://your-api-domain.com/products/${params.sku}`);
  const product = await res.json();

  // 商品不存在时返回404
  if (!product) {
    return { notFound: true };
  }

  return {
    props: { product },
    revalidate: 3600, // 每3600秒(1小时)重新生成页面,可根据需求调整
  };
}

export default function ProductDetail({ product }) {
  return (
    <div className="product-detail">
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <span>价格:{product.price}</span>
    </div>
  );
}

2. 服务端渲染(SSR)—— 用于实时数据场景

每次用户访问商品页面时,服务端都会实时调用API获取数据并渲染HTML返回,适合商品数据频繁更新的场景。

  • Pages Router中直接使用getServerSideProps,无需配置getStaticPaths

Pages Router 示例代码:

export async function getServerSideProps({ params }) {
  const res = await fetch(`https://your-api-domain.com/products/${params.sku}`);
  const product = await res.json();

  if (!product) {
    return { notFound: true };
  }

  return {
    props: { product },
  };
}

export default function ProductDetail({ product }) {
  return (
    <div className="product-detail">
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <span>价格:{product.price}</span>
    </div>
  );
}

3. App Router(Next.js 13+)实现

Next.js 13+的App Router默认使用服务端组件,直接在页面组件中异步获取数据即可,无需额外的getServerSideProps/getStaticProps:

// app/products/[sku]/page.js
async function fetchProduct(sku) {
  const res = await fetch(`https://your-api-domain.com/products/${sku}`, {
    // 实时获取数据:cache: 'no-store'
    // 或设置缓存时间:next: { revalidate: 3600 }
    cache: 'no-store',
  });

  if (!res.ok) {
    throw new Error('商品不存在');
  }

  return res.json();
}

export default async function ProductPage({ params }) {
  const product = await fetchProduct(params.sku);
  return (
    <div className="product-detail">
      <h1>{product.name}</h1>
      <p>{product.description}</p>
      <span>价格:{product.price}</span>
    </div>
  );
}

如果需要客户端交互(比如添加购物车按钮),可以在组件顶部添加'use client'指令,搭配SWR/React Query做数据获取,但这种方式首屏不会返回渲染后的HTML,仅适合交互优先的场景。

关于你的思路

你的思路完全没问题,Next.js本身就支持无需全量预渲染的动态路由方案。之前的404错误大概率是因为getStaticPaths的fallback参数配置错误(比如设为false),或者路由文件命名不符合Next.js的动态路由规则(比如没加[sku]后缀)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:19:54