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
相关产品推荐
相关产品推荐

