在Vercel中不使用fetch实现ISR遇报错,请求排查问题
问题原因与解决方案
错误根源
你在Pages Router的getStaticProps/getStaticPaths里调用了unstable_cache,但这个API是App Router专属的缓存工具——Pages Router的服务器端函数运行时没有unstable_cache所需的incrementalCache上下文,直接调用就会触发这个报错。
两种解决办法
1. 用Pages Router原生ISR方案(推荐)
Pages Router里实现ISR不需要额外用unstable_cache,直接通过getStaticProps的revalidate参数控制页面缓存,同时自己给数据库/GraphQL查询加缓存逻辑即可:
// pages/products/[id].js export async function getStaticPaths() { // 生成静态路径逻辑不变 const productIds = await getAllProductIdsFromDB(); return { paths: productIds.map(id => ({ params: { id } })), fallback: 'blocking' }; } export async function getStaticProps({ params }) { // 直接写数据库/GraphQL查询,可自行添加缓存(比如用Redis、内存缓存) const product = await queryProductFromDB(params.id); return { props: { product }, // ISR核心:设置缓存过期时间(单位:秒),到期后自动重新生成页面 revalidate: 60 }; }
2. 迁移到App Router使用unstable_cache
如果非要用Next.js官方的缓存API,就得把页面迁移到App Router,用generateStaticParams替代getStaticPaths,并在Server Component里调用unstable_cache:
// app/products/[id]/page.js import { unstable_cache } from 'next/cache'; // 定义带缓存的查询函数 const fetchProductWithCache = unstable_cache( async (productId) => { return await queryProductFromDB(productId); }, // 自定义缓存键,确保不同产品的缓存不冲突 ['product-details', productId], // 设置缓存过期时间 { revalidate: 60 } ); // 生成静态路径 export async function generateStaticParams() { const productIds = await getAllProductIdsFromDB(); return productIds.map(id => ({ id })); } // Server Component,直接调用缓存函数 export default async function ProductPage({ params }) { const product = await fetchProductWithCache(params.id); return <div>{product.name}</div>; }
额外提醒
unstable_cache带有unstable前缀,说明API还未稳定,生产环境使用前要做好兼容性测试。
内容的提问来源于stack exchange,提问作者Joey Yi Zhao
相关产品推荐
相关产品推荐

