如何让部署在Vercel的Next.js 13页面每次请求都服务端渲染?
解决Next.js 13 + next-sanity在Vercel上被静态生成的问题
问题场景
在Vercel部署的Next.js 13项目中,使用next-sanity客户端在服务端调用API时,Vercel无法识别client.fetch为动态请求,导致页面被静态生成,无法每次请求都触发服务端渲染。
解决方案
在页面组件所在文件中添加动态渲染配置,强制Next.js每次请求都执行服务端渲染:
修改后的代码示例
import { createClient, groq } from "next-sanity"; const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, dataset: process.env.NEXT_PUBLIC_SANITY_DATASET, apiVersion: process.env.NEXT_PUBLIC_SANITY_API_V, useCdn: false, }) // 强制页面每次请求都进行服务端渲染 export const dynamic = 'force-dynamic' export default async function Home() { const res = await client.fetch(groq`*[_type == "homes"] { _id, name }`); return ( <main> <div className="text-xs whitespace-pre"> {JSON.stringify(res, null, 2)} </div> </main> ); }
原理说明
Next.js 13的App Router默认会对没有动态依赖的页面进行静态优化。由于next-sanity的fetch调用未被Vercel的静态分析工具标记为动态操作,页面被自动静态生成。通过导出dynamic: 'force-dynamic',明确告知Next.js该页面需禁用静态优化,每次请求都在服务端执行渲染逻辑。
替代方案(可选)
如果你的页面需要访问请求头、Cookie等动态数据,也可以在组件中调用headers()或cookies()函数(无需实际使用返回值),Next.js会自动识别页面为动态页面:
import { headers } from 'next/headers' export default async function Home() { // 仅调用即可触发动态渲染 headers() const res = await client.fetch(groq`*[_type == "homes"] { _id, name }`); // ... 其余代码 }
内容的提问来源于stack exchange,提问作者Evanss
相关产品推荐
相关产品推荐

