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

使用next-sitemap生成Contentful动态站点地图时触发TypeError

Next.js + next-sitemap + Contentful 动态站点地图报错:fields.map is not a function

在基于nextjs-contentful-blog-starter搭建的Next.js站点中,使用next-sitemap生成Contentful动态站点地图时出现以下错误:

error Error [TypeError]: fields.map is not a function

相关代码文件

/src/pages/sitemap.xml/index.js

import { getServerSideSitemap } from "next-sitemap";
import ContentfulApi from "@/utils/ContentfulApi";
import { Config } from "@/utils/Config";

export const getServerSideProps = async (ctx) => {
  // 从Contentful获取链接
  const blogPostSlugs = await ContentfulApi.getAllPostSlugs();

  const blogPostFields = blogPostSlugs.map((slug) => {
    return {
      loc: `${Config.url}/blog/${slug}`,
      lastmod: new Date().toISOString(),
    };
  });

  const totalPosts = await ContentfulApi.getTotalPostsNumber();
  const totalPages = Math.ceil(totalPosts / Config.pagination.pageSize);

  const blogIndexPageFields = [];

  /**
   * 从第2页开始,避免重复生成首页(即第1页)的链接
   */
  for (let page = 2; page <= totalPages; page++) {
    blogIndexPageFields.push({
      loc: `${Config.url}/blog/page/${page}`,
      lastmod: new Date().toISOString(),
    });
  }

  const fields = blogPostFields.concat(blogIndexPageFields);
  return getServerSideSitemap(ctx, fields);
};

const Sitemap = () => {
  return null;
};

export default Sitemap;

/next-sitemap.js

module.exports = {
  siteUrl: "http://localhost:3000/",
  generateRobotsTxt: true, // (可选)
  robotsTxtOptions: {
    policies: [{ userAgent: "*", disallow: "/api" }],
    additionalSitemaps: [
      "http://localhost:3000/sitemap.xml",
    ],
  },
  exclude: ["/api/*", "/sitemap.xml"],
};

ContentfulApi 相关GraphQL代码片段

...
static async getPageContentBySlug(slug, options = defaultOptions) {
    const variables = { slug, preview: options.preview };
    const query = `
    query GetPageContentBySlug($slug: String!, $preview: Boolean!) {
      pageContentCollection(limit: 1, where: {slug: $slug}, preview: $preview) {
        items {
          sys {
            id
          }
          title
          description
          slug
          body {
            json
            links {
              entries {
                block {
                  sys {
                    id
                  }
                  __typename
                  ... on VideoEmbed {
                    title
                    embedUrl
                  }
                  ... on CodeBlock {
                    description
                    language
                    code
                  }
                  ... on FaqBlock {
                    question
                    answer
                    active
                    first
                  }
                }
              }
              assets {
                block {
                  sys {
                    id
                  }
                  url
                  title
                  width
                  height
                  description
                }
              }
            }
          }
        }
      }
    }`;

    const response = await this.callContentful(query, variables, options);

    const pageContent = response.data.pageContentCollection.items
      ? response.data.pageContentCollection.items
      : [];

    return pageContent.pop();
  }

  static async getPaginatedSlugs(page) {
    const queryLimit = 100;
    const skipMultiplier = page === 1 ? 0 : page - 1;
    const skip = skipMultiplier > 0 ? queryLimit * skipMultiplier : 0;

    const variables = { limit: queryLimit, skip };

    const query = `query GetPaginatedSlugs($limit: Int!, $skip: Int!) {
        blogPostCollection(limit: $limit, skip: $skip, order: date_DESC) {
          total
          items {
            slug
            }
          }
        }`;

    const response = await this.callContentful(query, variables);

    const { total } = response.data.blogPostCollection;
    const slugs = response.data.blogPostCollection.items
      ? response.data.blogPostCollection.items.map((item) => item.slug)
      : [];

    return { slugs, total };
  }

  
  static async getAllPostSlugs() {
    let page = 1;
    let shouldQueryMoreSlugs = true;
    const returnSlugs = [];

    while (shouldQueryMoreSlugs) {
      const response = await this.getPaginatedSlugs(page);

      if (response.slugs.length > 0) {
        returnSlugs.push(...response.slugs);
      }

      shouldQueryMoreSlugs = returnSlugs.length < response.total;
      page++;
    }

    return returnSlugs;
  }
...

解决方案

将getServerSideSitemap替换为getServerSideSitemapLegacy即可解决该错误:

  1. 修改导入语句:
import { getServerSideSitemapLegacy } from "next-sitemap";
  1. 修改返回语句:
return getServerSideSitemapLegacy(ctx, fields);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 01:47:31