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

Next.js静态站点生成(SSG)中标签动态页面创建报错及解决方案咨询

解决Next.js SSG标签动态页面的路径错误问题

你遇到的Error: A required parameter (slug) was not provided as a string in getStaticPaths错误,核心原因是你在getStaticPaths里错误地处理了标签数组:每个文章的contentfulMetadata.tags是一个数组(一篇文章可关联多个标签),直接访问tags.id会返回undefined,不符合Next.js对slug参数必须为字符串的要求。同时你还需要避免生成重复的标签路径(多个文章可能共享同一标签)。

下面是完整的修复方案:

1. 修复getStaticPaths:收集唯一标签并生成合法路径

我们需要先从所有文章中提取所有唯一的标签ID,再为每个标签生成对应的静态路径:

import { getArticles } from "../../../utils/contentful";

export async function getStaticPaths() {
  const data = await getArticles();
  // 用Set自动去重,收集所有标签ID
  const uniqueTagIds = new Set();
  
  data.articleCollection.items.forEach(article => {
    article.contentfulMetadata.tags.forEach(tag => {
      uniqueTagIds.add(tag.id);
    });
  });

  return {
    paths: Array.from(uniqueTagIds).map(tagId => ({
      params: { slug: tagId } // 与你CategorySection组件中的href参数保持一致
    })),
    fallback: false
  };
}

2. 修复getStaticProps:获取对应标签的所有文章

原来的getArticle函数是获取单篇文章的,我们需要获取所有关联指定标签的文章。首先在utils/contentful.js中新增一个查询函数:

// utils/contentful.js
export async function getArticlesByTag(tagId) {
  // 替换为你的Contentful查询逻辑,筛选带有指定标签的文章
  const response = await client.getEntries({
    content_type: "article", // 你的文章Content Type ID
    "contentfulMetadata.tags.sys.id": tagId
  });
  return response;
}

然后修改getStaticProps逻辑:

import { getArticlesByTag } from "../../../utils/contentful";

export async function getStaticProps(context) {
  const tagId = context.params.slug;
  const data = await getArticlesByTag(tagId);
  
  // 从返回的文章中提取当前标签的名称(避免额外请求标签数据)
  const tagName = data.items[0]?.contentfulMetadata.tags.find(
    tag => tag.id === tagId
  )?.name || "Unnamed Category";

  return {
    props: {
      articles: data.items,
      tagName
    }
  };
}

3. 更新Category组件:展示标签下的文章列表

修改组件以展示标签名称和对应的文章列表:

import Link from "next/link";

export default function Category({ articles, tagName }) {
  return (
    <div className="category-page">
      <h1>Articles in: {tagName}</h1>
      <div className="article-list">
        {articles.map(article => (
          <div key={article.sys.id} className="article-item">
            <Link href={`/articles/${article.fields.slug}`}>
              <a>{article.fields.title}</a>
            </Link>
            <p>{article.fields.excerpt}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

4. 优化CategorySection组件(可选但推荐)

为避免React的key警告,给map循环的元素添加唯一key:

import Link from "next/link";
export default function CategorySection({ categories }) {
  return (
    <Wrapper>
      <ContentWrapper>
        <CategoryWrapper>
          {categories.map((category) => (
            <React.Fragment key={category.sys.id}>
              {category.contentfulMetadata.tags.map((tag) => (
                <Link key={tag.id} href={`/articles/categories/${tag.id}`}>
                  <Categories>{tag.name}</Categories>
                </Link>
              ))}
            </React.Fragment>
          ))}
        </CategoryWrapper>
      </ContentWrapper>
    </Wrapper>
  );
}

这样修改后,点击标签就能正确导航到对应的动态页面,展示所有关联该标签的文章了。

内容的提问来源于stack exchange,提问作者Mathias Riis Sorensen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 15:38:12