Next.js getStaticPaths在Vercel生产环境斜杠被转%2F问题
Next.js 动态路由生产环境URL出现%2F的解决方法
问题描述
我为静态文档页面实现了Next.js动态路由,本地运行和编译都正常,但生产环境URL无法正常工作。问题出在getStaticPaths的URL处理上,导致URI中出现奇怪的%2F值,预期路径应该是example.com/docs/en-integrations-hello-test。
原代码
export const getStaticPaths = async () => { // get current path const myProdPath = path.join(process.cwd(), 'src/') // grab all markdown files const docPaths = await glob(path.join(myProdPath, '**/*.md')) // For each filename, the slug is the filename without the .md extension const paths = await docPaths.map((docPath) => { const slug = docPath .replace(myProdPath, '') .replace('.md', '') console.log('this is slug: ' + slug) // prints out correctly without %2F return { params: { slug: [slug] } } }) // Return the possible paths return { paths, fallback: true } }
解决方法
问题根源
你返回的slug是包含路径分隔符的字符串(比如en/integrations/hello-test),但将其作为单个元素的数组传给params.slug时,Next.js会对整个字符串进行URL编码,导致/被转义为%2F。而[...slug].tsx这种捕获所有片段的动态路由,需要的是拆分后的路径片段数组。
修复后的代码
import path from 'path'; import glob from 'glob'; export const getStaticPaths = async () => { const myProdPath = path.join(process.cwd(), 'src/'); const docPaths = await glob(path.join(myProdPath, '**/*.md')); const paths = docPaths.map((docPath) => { let slug = docPath .replace(myProdPath, '') .replace('.md', ''); // 将slug按路径分隔符拆分,并过滤空元素 const slugSegments = slug.split('/').filter(segment => segment); return { params: { slug: slugSegments } }; }); return { paths, fallback: true }; };
补充说明
- 若原
slug为en/integrations/hello-test,拆分后会得到数组['en', 'integrations', 'hello-test'],Next.js会自动拼接成正确的路径/docs/en/integrations/hello-test(假设你的路由文件位于pages/docs/[...slug].tsx) - 无需手动处理URL编码,Next.js会自动处理路径片段的编码逻辑
内容的提问来源于stack exchange,提问作者husky
相关产品推荐
相关产品推荐

