首页 > 解决方案 > Nextjs - 内容丰富 - 标签 - 动态页面

问题描述

当我点击文章或我网站上其他地方的标签时,我想创建动态页面。

我正在使用 Next.js、SSG,并使用以下 GraphQL 查询从 Contentful 中获取包含标签的文章:

export async function getArticles() {
  const articlesQuery = gql`
    {
      articleCollection(order: date_DESC) {
        items {
          title
          slug
          excerpt
          date
          contentfulMetadata {
            tags {
              name
              id
            }
          }
          featuredImage {
            title
            url
            width
            height
          }
          author {
            name
            photo {
              fileName
              url
              width
              height
            }
            title
            twitterProfile
            linkedInProfile
            slug
          }
        }
      }
    }
  `;
  return graphQLClient.request(articlesQuery);
}
export async function getArticle(slug) {
  const articleQuery = gql`
    query getArticle($slug: String!) {
      articleCollection(limit: 1, where: { slug: $slug }) {
        items {
          title
          slug
          excerpt
          date
          contentfulMetadata {
            tags {
              name
              id
            }
          }
          featuredImage {
            title
            url
            width
            height
          }
          author {
            name
            photo {
              fileName
              url
              width
              height
            }
            title
            twitterProfile
            linkedInProfile
            slug
          }
          content {
            json
            links {
              entries {
                block {
                  sys {
                    id
                  }
                  __typename
                  ... on VideoEmbed {
                    title
                    embedUrl
                  }
                  ... on CodeBlock {
                    description
                    language
                    code
                  }
                }
              }
              assets {
                block {
                  sys {
                    id
                  }
                  url
                  title
                  width
                  height
                }
              }
            }
          }
        }
      }
    }
  `;

  return graphQLClient.request(articleQuery, {
    slug,
  });
}

contentfulMetadata 是标签的来源:

contentfulMetadata {
            tags {
              name
              id
            }
          }

这是我的 [id].jsx 文件:

import { getArticles, getArticle } from "@utils/contentful";

export async function getStaticPaths() {
  const data = await getArticles();

  return {
    paths: data.articleCollection.items.map((article) => ({
      params: { id: article.contentfulMetadata.tags[0].id },
    })),
    fallback: false,
  };
}

export async function getStaticProps(context) {
  const data = await getArticle(context.params.id);

  return {
    props: { article: data.articleCollection.items[0] },
  };
}

export default function TagPage({ article }) {
  return (
    <div>
      <h1>{article.contentfulMetadata.tags.id}</h1>
    </div>
  );
}

我收到以下错误: Error: Error serializing `.article` returned from `getStaticProps` in "/tags/[id]". Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

console.log(data.articleCollection.items.contentfulMetadata.tags.id);console.log(data.articleCollection.items.contentfulMetadata.tags[0].id);在 getStaticPaths 函数中时,它会提供以下错误: TypeError: Cannot read property 'tags' of undefined

谁能展示如何创建一个动态页面 ([id].jsx) 文件,该文件将标签 id 显示为标题<h1>以及包含相同标签的所有文章?

标签: graphqltagsnext.jscategoriescontentful

解决方案


内容丰富的 DevRel 在这里。

article.contentfulMetadata.tags是一个数组,因为一个条目可以有多个标签。因此,您需要通过article.contentfulMetadata.tags[0].idorarticle.contentfulMetadata.tags[desired_index].id等​​方式访问您想要的标签。

这是一个示例 GraphQL 查询:

query {
  blogPostCollection {
    items {
      contentfulMetadata {
        tags {
          id
          name
        }
      }
    }  
  }
}

这是带有标签作为数组的响应:

  "data": {
    "blogPostCollection": {
      "items": [
        {
          "contentfulMetadata": {
            "tags": [
              {
                "id": "salmastag",
                "name": "Salma s tag"
              }
            ]
          }
        },
        {
          "contentfulMetadata": {
            "tags": []
          }
        }
      ]
    }
  }
}

请注意,如果博客文章没有分配任何 PUBLIC 标记(响应中的第二个条目),则会返回一个空数组——您可能需要为此在代码中进行一些安全检查。


推荐阅读