Vercel环境Next.js fallback重写通过next/link访问无getServerSideProps props
这是Vercel部署环境下Next.js重写规则阶段与客户端跳转逻辑的兼容性问题,核心原因是fallback阶段的重写规则仅在服务端生效,而next/link的客户端跳转优先使用本地路由配置,不会触发服务端的fallback重写逻辑,进而跳过getServerSideProps执行。以下是具体调试步骤和解决办法:
1. 先做调试验证
- 查看函数执行日志:在Vercel控制台的「Functions」标签下,检查目标页面的
getServerSideProps是否在next/link跳转时有日志输出。如果没有,说明客户端跳转完全没触发服务端请求。 - 检查客户端路由规则:在浏览器控制台执行
window.__NEXT_DATA__.routes,查看客户端侧加载的路由规则是否包含你的fallback重写。如果缺失,说明客户端未同步该规则,跳转时直接走本地路由逻辑。 - 强制触发服务端请求测试:在跳转的
next/link组件中添加shallow={false},比如:
如果此时能正常获取服务端Props,即可确认是客户端浅渲染导致的问题。<Link href="/your-fallback-path" shallow={false}>跳转至目标页</Link>
2. 可行的解决办法
方法一:调整重写规则的阶段(最直接)
把fallback中的重写规则移到afterFiles阶段,只要规则不会和静态文件、已有页面路由冲突,就能保证客户端和服务端都能正确匹配规则,跳转时自动触发getServerSideProps。
方法二:强制客户端跳转触发服务端请求
如果必须保留fallback阶段的规则,在所有指向该规则目标的next/link或router.push中,强制关闭浅渲染:
// 使用Link组件 <Link href="/target-url" shallow={false}>跳转</Link> // 使用router.push import { useRouter } from 'next/router'; const router = useRouter(); const handleJump = () => { router.push('/target-url', undefined, { shallow: false }); };
这会强制跳转时向服务端发起完整请求,触发getServerSideProps执行。
方法三:同步本地与Vercel的Next.js版本
检查本地开发的Next.js版本和Vercel部署时使用的版本是否一致,版本差异可能导致路由解析逻辑不同。可以在package.json中锁定Next.js版本后重新部署。
3. 原理补充
Vercel部署时会将beforeFiles、files、afterFiles阶段的重写规则编译到客户端路由配置中,而fallback阶段的规则仅在服务端生效。当用next/link跳转时,客户端会优先匹配本地路由规则,若匹配不到才会走服务端请求;但fallback规则不在客户端配置里,所以客户端会直接渲染对应路径的页面(如果存在),跳过服务端的重写和getServerSideProps执行。只有直接访问或刷新页面时,请求才会到达服务端,走完整的重写流程。
内容的提问来源于stack exchange,提问作者user5801710

