やりたいこと
サイドバーにカテゴリー一覧を表示している。
表示されているカテゴリを選択した際に、カテゴリに紐づく記事を表示したい
サイドバーは下記
カテゴリーを全て取得して表示しているだけです
components/Sidebar.js
import React from "react"
import { Container, Row, Nav } from "react-bootstrap"
import { useStaticQuery, Link, graphql } from "gatsby"
import Styles from "./sidebar.module.css"
const Sidebar = () => {
const data = useStaticQuery(graphql`
query {
allContentfulCategory {
edges {
node {
title
slug
id
createdJP: createdAt(formatString: "Y年MM月DD日")
}
}
}
}
`)
const categories = data.allContentfulCategory.edges
return (
<div className={Styles.sidebar}>
<Row>
<div className="col-lg-12">
<div className={Styles.sidebar_item}>
<div className={Styles.sidebar_heading}>
<h2>Categories</h2>
</div>
<div className="content">
<Nav className={Styles.categories}>
{categories.map(({ node }) => (
<Nav.Link
key={node.id}
as={Link}
to={`/category/${node.slug}`}
>
{node.title}
</Nav.Link>
))}
</Nav>
</div>
</div>
</div>
</Row>
</div>
)
}
export default Sidebar
やりかた
gatsby-node.jsで各投稿ページのように、カテゴリ別を作成してやる
1.カテゴリごとのページを作成
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// 使うテンプレのパス
const categoryTemplate = path.resolve(`./src/templates/category.js`)
const result = await graphql(
`
{
allContentfulCategory {
edges {
node {
slug
id
}
}
}
}
`
)
if (result.errors) {
throw result.errors
}
const categories = result.data.allContentfulCategory.edges
categories.forEach(category => {
createPage({
path: `category/${category.node.slug}`,
component: categoryTemplate,
context: {
id: category.node.id,
slug: category.node.slug,
},
})
})
}
カテゴリごとのページのテンプレート作成
const categoryTemplate = path.resolve(``./src/templates/category.js``)で記述したように
カテゴリの個別ページのテンプレートを作成する
今回は/src/templates/category.jsで作成
あとは、個別投稿と同じようになる
GraphQLでidと一致するカテゴリを取得し、それに紐づくblogpostをループして表示
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
const Category = ({ data }) => {
const category = data.contentfulCategory
const posts = data.contentfulCategory.blogpost
return (
<Layout>
<h1 className="p-3">{category.title}</h1>
{posts.map(post => {
return (
<div> {post.title}</div>
)
})}
</Layout>
)
}
export default Category
export const pageQuery = graphql`
query($id: String!) {
contentfulCategory(id: { eq: $id }) {
id
slug
title
blogpost {
id
slug
title
}
}
}
`