Next.js静态嵌套动态路由嵌套迭代时getStaticPaths返回空数组问题
问题根因
paths返回空数组的核心原因是 Array.prototype.forEach不支持异步等待:你为forEach传入了async回调,但JS运行时不会等待所有回调内的Supabase异步请求执行完成,就会直接执行后续的return语句,此时所有分类下的文章计数查询还未返回结果,paths自然是空数组。
另外你原有代码中还存在两处可优化的细节:
- 你在
params中传入了多余的categoryId参数,你的路由规则为/categories/[category]/[page],仅需要category和page两个参数即可 - Next.js要求动态路由参数必须为字符串类型,数字类型的页码会触发构建报错
修复方案
方案1:串行实现(逻辑更直观)
把forEach替换为支持异步等待的for...of循环即可:
// pages/categories/[category]/[page].js export async function getStaticPaths() { const paths = [] // 查询分类列表 const { data: categories, error: categoryError } = await supabase.from('categories').select('id, name') if (categoryError || !categories) return { paths: [], fallback: false } // 遍历每个分类查询对应文章数 for (const c of categories) { const { count, error: postError } = await supabase .from('posts') .select('id', { count: 'exact', head: true }) .eq('category_id', c.id) if (postError || !count) continue // 按每页1条的规则生成所有页码路径 for (let i = 0; i < count; i++) { paths.push({ params: { page: String(i + 1), // 转为字符串符合Next.js路由参数要求 category: c.name } }) } } return { paths, fallback: false } }
方案2:并行实现(性能更优)
如果分类数量较多,可使用Promise.all并行发起所有文章计数请求,减少请求等待时间:
export async function getStaticPaths() { const { data: categories, error } = await supabase.from('categories').select('id, name') if (error || !categories) return { paths: [], fallback: false } // 并行查询所有分类对应的文章数并生成路径 const pathGroups = await Promise.all( categories.map(async (c) => { const { count } = await supabase .from('posts') .select('id', { count: 'exact', head: true }) .eq('category_id', c.id) return Array.from({ length: count }, (_, i) => ({ params: { page: String(i + 1), category: c.name } })) }) ) // 二维数组合并为一维路径数组 const paths = pathGroups.flat() return { paths, fallback: false } }
内容的提问来源于stack exchange,提问作者Fransisco Wijaya
相关产品推荐
相关产品推荐

