[Gatsby]タグページを作る

August 5th, 2020

タグ別に記事を表示するページを実装します。

実装

ページ生成処理の修正

タグページが生成されるようにページ生成処理を修正します。

GraphQLクエリの作成

タグの一覧を取得するクエリを作成します。開発環境を立ち上げてhttp://localhost:8000/___graphqlへアクセスするとGraphQLのエディタを使えます。タグの一覧が取れれば良いので以下のようなクエリを作りました。

query MyQuery {
  allContentfulBlogPost {
    group(field: tags) {
      fieldValue
    }
  }
}

gatsby-node.jsの修正

元から書かれていたブログ記事取得用のクエリと、タグ一覧取得用のクエリがマージできそうだったので、マージして以下のように変更しました。

gatsby-node.js
{
  allContentfulBlogPost {
    group(field:tags) {
      fieldValue
    }
    edges {
      node {
        title
        slug
      }
    }
  }
}

ページのtemplateをまだ作成していないので、一旦コンソールにタグを表示するコードを書いて動作確認をします。

gatsby-node.js
        const tags = result.data.allContentfulBlogPost.group
        tags.forEach((tag, index) => {
          console.log(tag.fieldValue)
        })

この状態でyarn run devを実行してコンソールにタグの一覧が出力されれば成功です。

ページ用テンプレートの作成

タグ付けされた記事の一覧を表示するページのテンプレートを作成します。ブログ一覧用のtsxファイルの中身をコピペしてからpageQueryを修正します。filterを付けて記事をタグで選択するようにしています。

tag-article.tsx
  query TagArticle($tag: String!) {
    site {
      siteMetadata {
        title
      }
    }
    allContentfulBlogPost(sort: { fields: [publishDate], order: DESC }, filter: {tags: {eq: $tag}}) {
      edges {
        node {
          title
          slug
          publishDate(formatString: "MMMM Do, YYYY")
          tags
          heroImage {
            fluid(maxWidth: 350, maxHeight: 196, resizingBehavior: SCALE) {
              ...GatsbyContentfulFluid_tracedSVG
            }
          }
          description {
            childMarkdownRemark {
              html
            }
          }
        }
      }
    }
  }
`

ページ生成処理の修正(再)

タグをコンソールに出力していた部分をページ生成のコードへ直します。

gatsby-node.js
const tagArticle = path.resolve('./src/templates/tag-article.tsx')
.
.
.
const tags = result.data.allContentfulBlogPost.group
tags.forEach((tag, index) => {
  createPage({
    path: `/tag/${tag.fieldValue}/`,
    component: tagArticle,
    context: {
      tag: tag.fieldValue
    },
  })
})

これでタグ付けされた記事の一覧ページが完成です。

タグをリンクにする

せっかく作ったタグページへの動線がないので、既存のタグ表示箇所をリンクに変えます。まずはコンポーネントを作成します。

tag.tsx
import React from 'react'
import { Link } from 'gatsby'
const styles = require('./article-preview.module.css')

type Props = {
  tag: string
}

const Component: React.FC<Props> = props => {
  return (
    <p className={styles.tag} key={props.tag}>
      <Link to={`/tag/${props.tag}`}>{props.tag}</Link>
    </p>
  )
}

export default Component

あとは既存のタグ表示箇所をこのコンポーネントに置き換えれば無事ページ遷移もできるようになります。

artile-preview.tsx
{props.tags &&
  props.tags.map(tag => (
    <Tag tag={tag} />
  ))}