如何为Next.js+GraphQL应用生成全量动态URL站点地图?
解决Next.js动态路由站点地图只生成部分条目的问题
核心原因
你遇到的问题是next-sitemap不会自动抓取所有动态路由的slug,而之前通过ApolloClient查询时未处理GraphQL的分页逻辑,仅获取了默认返回的48条数据。
解决方案
修改next-sitemap.config.js,通过分页循环查询所有食谱的slug,再生成完整路由:
const { ApolloClient, InMemoryCache, gql } = require('@apollo/client'); // 初始化Apollo客户端 const client = new ApolloClient({ uri: '你的GraphQL接口地址', cache: new InMemoryCache(), // 接口需认证时添加headers,示例: // headers: { // Authorization: `Bearer ${process.env.API_TOKEN}` // } }); module.exports = { siteUrl: "MY_WEB_URL", generateRobotsTxt: true, // 自定义生成路由的函数 generateRoutes: async () => { const routes = []; let hasMore = true; let offset = 0; const pageSize = 100; // 单次查询条目数,可根据接口性能调整 while (hasMore) { const { data } = await client.query({ query: gql` query GetRecipeSlugs($limit: Int!, $offset: Int!) { recipes(limit: $limit, offset: $offset) { slug } } `, variables: { limit: pageSize, offset }, }); // 当前页无数据时终止循环 if (!data.recipes || data.recipes.length === 0) { hasMore = false; break; } // 将slug转换为完整路由 data.recipes.forEach(recipe => { routes.push(`/recipes/${recipe.slug}`); }); // 累加偏移量,获取下一页数据 offset += pageSize; } return routes; }, };
注意事项
- 若你的GraphQL接口采用游标分页(cursor-based),需调整查询逻辑:每次查询后记录最后一条数据的cursor,下一次查询传入
after: cursor参数,直到返回的pageInfo.hasNextPage为false。 - 合理设置
pageSize:过大可能导致接口超时,过小会增加查询次数,根据API性能平衡调整。 - 确保Node构建环境能正常访问GraphQL接口:若接口有防火墙或IP限制,需允许构建环境的IP访问。
- 运行
next-sitemap前,确认API地址、认证令牌等环境变量已正确配置。
内容的提问来源于stack exchange,提问作者Navro
相关产品推荐
相关产品推荐

