You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:06:07