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

NextJS 13 App目录双层嵌套动态路由静态生成配置咨询

双动态路由下的静态生成配置方案

针对你在Next.js 13 App Router中subpage/[categoryName]/[gifId]双动态路由的静态生成需求,以下是完整实现方案,包含前端代码调整和后端接口适配建议:

1. 前端代码调整

修改subpage/[categoryName]/[gifId]/page.tsx中的类型定义、参数生成逻辑及数据请求逻辑,适配双动态参数:

import MyComponent from "../../../components/MyComponent";
import { PartialGifProps, TagType, CategoryType } from "../../../utils/typings";
import axios from "axios";
import { apiDomain, defaultHeaders } from "../../../utils/constants";

const perPage = 40;

// 更新Props类型,包含两个动态路由参数
type Props = {
  params: {
    categoryName: string;
    gifId: string;
  };
};

export const generateStaticParams = async () => {
  // 1. 获取所有分类列表(需后端新增接口返回全部分类)
  const categoriesRes = await axios.get(`${apiDomain}/get_categories`, {
    headers: defaultHeaders,
  });
  const categories: CategoryType[] = categoriesRes.data;

  const paramsList: { categoryName: string; gifId: string }[] = [];

  // 2. 遍历每个分类,生成对应分页的参数组合
  for (const category of categories) {
    const categoryName = category.name; // 假设分类对象包含name字段
    // 调用按分类统计总数的接口(需后端修改get_gif_count支持category参数)
    const countRes = await axios.get(`${apiDomain}/get_gif_count`, {
      headers: defaultHeaders,
      params: { category: categoryName },
    });
    const { total_count: totalCount }: TagType = countRes.data;
    const totalPages = Math.ceil(totalCount / perPage);

    // 为当前分类的每一页生成参数
    for (let i = 1; i <= totalPages; i++) {
      paramsList.push({
        categoryName,
        gifId: i.toString(),
      });
    }
  }

  // 最终参数列表示例:
  // [
  //   { categoryName: 'fashion', gifId: '1' },
  //   { categoryName: 'fashion', gifId: '2' },
  //   { categoryName: 'technology', gifId: '1' },
  //   ...
  // ]
  return paramsList;
};

// 页面组件同时接收categoryName和gifId参数
const MyPage = async ({ params: { categoryName, gifId } }: Props) => {
  // 请求时携带分类参数,获取对应分类下的分页数据(需后端修改get_partial支持category参数)
  const url = `${apiDomain}/get_partial?page=${gifId}&per_page=${perPage}&category=${categoryName}`;
  const fetchGifs = await axios.get(url, { headers: defaultHeaders });
  const { gifs }: PartialGifProps = fetchGifs.data;

  return (
    <div className='text-white'>
      <MyComponent gifs={gifs} />
    </div>
  );
};

export default MyPage;

2. 后端接口适配

需要对现有接口做三处调整:

  • 新增/get_categories接口:返回所有分类列表(格式示例:[{name: 'fashion'}, {name: 'technology'}, ...])
  • 修改/get_gif_count接口:支持接收category查询参数,返回对应分类下的总GIF数量
  • 修改/get_partial接口:支持接收category查询参数,返回对应分类下指定页码的GIF数据

3. 处理subpage/[categoryName]路径问题

在subpage/[categoryName]/page.tsx中添加代码,处理单独访问分类路径的情况:

import { redirect } from 'next/navigation';

// 方案1:重定向到该分类的第一页
const CategoryPage = async ({ params: { categoryName } }) => {
  redirect(`/subpage/${categoryName}/1`);
};

// 方案2:返回404提示
// const CategoryPage = () => {
//   return <div className="text-white">该页面不存在,请访问具体的GIF分页</div>;
// };

export default CategoryPage;

内容的提问来源于stack exchange,提问作者kar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 15:25:24