関連記事を表示 | Gatsbyブログカスタマイズ

Webサイト高速化のための 静的サイトジェネレーター活用入門を通じて作成したこのブログのカスタマイズとして、個別記事下部に関連記事の表示を加えました。

関連記事表示の仕様

参考サイトのコードを参考に、以下の仕様としました。

  • 自身の記事以外が対象

  • 自身の記事が属する同カテゴリーの記事が対象

  • 複数カテゴリーを持つ場合でも最初(プライマリー)のカテゴリーにのみ対応

  • 表示は5つかつランダム

relatedposts.jsの作成

src/components/relatedposts.jsを新規作成します。

import React from "react"
import { graphql, useStaticQuery, Link } from "gatsby"

const RelatedPosts = props => {
  const randomSelect = (array, num) => {
    let newArray = []

    while (newArray.length < num && array.length > 0) {
      const rand = Math.floor(Math.random() * array.length)
      newArray.push(array[rand])
      array.splice(rand, 1)
    }

    return newArray
  }

  const data = useStaticQuery(graphql`
    query {
      allContentfulBlogPost {
        nodes {
          title
          slug
          id
          category {
            id
          }
        }
      }
    }
  `)

  const baseposts = data.allContentfulBlogPost.nodes.filter(
    node => node.id !== props.id && node.category.map(cat => (cat.id))[0] === props.catId
  )
  const relatedposts = randomSelect(baseposts, props.a_number)

  // 関連記事がなければ表示しない
  if (!relatedposts.length) {
    return null;
  }

  return (
    <div className="relatedposts">
      <h3>関連記事</h3>
      <ul>
        {relatedposts.map(node => {
          return (
            <li key={node.slug}>
              <Link to={`/blog/post/${node.slug}/`}>{node.title}</Link>
            </li>
          )
        })}
      </ul>
    </div>
  )
}

export default RelatedPosts

blogpost-template.jsの編集

src/templates/blogpost-template.jsを編集します。

まず、上部で作成したRelatedPostsをimportします。

// Before
...
import Layout from "../components/layout"

// After
...
import Layout from "../components/layout"
import RelatedPosts from "../components/relatedposts"

前後の記事メニュー直下で、作成したコンポーネントを使用します。

//Before
<div className="postbody">
...
</div>
<ul className="postlink">
...
</ul>

//After
<div className="postbody">
...
</div>
<ul className="postlink">
...
</ul>
<RelatedPosts a_number={5} id={pageContext.id} catId={data.contentfulBlogPost.category.map(cat => (cat.id))[0]} />

a_numberで表示する記事数を設定、idで自身の記事ID、catIdで自身の記事が属する同カテゴリーID(最初(プライマリー)のカテゴリー)を定義しています。

最後に、CSSで適度にスタイルを調整します。

参考サイト

▼GatsbyJSでのクエリデータの扱い(静的生成後の記事一覧のランダム表示) | エビスコム - EBISUCOM
https://ebisu.com/note/gatsbyjs-querydata/

▼yopinoji.com | Gatsby で作成したブログに関連記事を表示する
https://yopinoji.com/gatsby-js-related-posts