前にやった、contentfulからデータを取得してgatsby.jsでページを作成するやつ、やり方忘れたので思い出しながらまとめてみる。
以下の本に書いてあるやつなので、より詳しく知りたい方は購入をおすすめします。なかなか良い本でした。
【特典付き! 】Webサイト高速化のための 静的サイトジェネレーター活用入門 (Compass Booksシリーズ)
contentful上で記事を作成
割愛
GraphQLでcontentfulのデータを扱えるようにする
$ yarn add gatsby-source-contentful
// gatsby-config.js
...
`other-plugin-hoge`,
{
resolve: `gatsby-source-contentful`,
options: {
spaceId: process.env.CONTENTFUL_SPACE_ID,
accessToken: process.env.CONTENTFUL_ACCESS_TOKEN,
host: process.env.CONTENTFULHOST,
},
},
],
}
http://localhost:8000/___graphql を開いてallContentful~、contentful~ という項目が増えていることを確認。
記事のテンプレートファイルを作成
$ mkdir src/templates
$ touch src/templetes/blogpost-template.js
https://localhost:8000/__graphql を開いてクエリを作成し、テンプレートファイル下部に貼り付け。
// src/templates/blogpost-template.js
import React from "react"
import { graphql } from "gatsby"
export default({ data }) => (
<div>
<h1>{data.contentfulBlogPost.title}</h1>
</div>
)
export const query = graphql`
query {
contentfulBlogPost {
title
}
}
`
gatsby-node.jsを作成
$ touch gatsby-node.js
Gatsbyがページを生成する際、特定のタイミングやイベントに合わせて処理をさせたいケースがあります。そうした処理を設定するのがgatsby-node.jsです。
GatsbyNodeAPIとして様々なAPIが用意されており、関数の形でexportすることで利用します。ここではcreatePagesを使います。
//gatsby-node.js
const path = require("path")
exports.createPages = async({ graphql, actions, reporter }) => {
const { createPage } = actions
}
クエリを生成する
http://localhost:8000/___graphql を開く
allContentfulBlogPost > edges > node > id, slug あたりにチェックを入れてクエリを生成
クエリを追加する
生成したクエリをgatsby-node.jsに追加。クエリの結果はblogresultに受け取る。クエリでエラーが発生した場合のメッセージ表示処理も合わせて実装。
//gatsby-node.js
const path = require("path")
exports.createPages = async({ graphql, actions, reporter }) => {
const { createPage } = actions
const blogresult = await graphql(`
query {
{ここにクエリをペースト}
}
`)
if(blogresult.errors) {
reporter.panicOnBuild(`GraphQLのクエリでエラーが発生しました`)
return
}
}
createPageでページを生成する
クエリで取得したデータからforEachメソッドで各記事のデータを取り出し、ページを生成。ページの生成にはcreatePagesを使って、以下のように設定。
path
生成するページのパス。ここではblog/post/スラッグ をセット
component
生成に使用するテンプレート。gatsby-node.jsからの相対パスで指定。ここではblogpost-template.jsを指定。
//gatsby-node.js
const path = require("path")
exports.createPages = async({ graphql, actions, reporter }) => {
...
const blogresult = ...
if(blogresult.errors) {
...
}
blogresult.data.allContentfulBlogPost.edges.forEach(({ node })) => {
createPage({
path: `/blog/post/${node.slug}`
component: path.resolve(`./src/templates/blogpost-template.js`)
})
}
}
これで記事ページが生成される。開発サーバーを起動し直して404ページを表示すると、ページが追加されていることが確認できる。
ただしこの段階では、全てのページで同じ内容が表示されてしまう。
記事ごとにデータを読み込んでページを生成
記事ごとに別のデータを読み込むため、テンプレート(blogpost-template.js)に各記事のIDを送り、そのIDを使ってデータを取得するように修正する。
//gatsby-node.js
blogresult.dta.allContentfulBlogPost.edges.forEach(({ node })) => {
createPage({
path: `/blog/post/${node.slug}`
component: path.resolve(`./src/templates/blogpost-template.js`),
context: {
id: node.id,
}
})
}
}
contextで指定されたデータは、$をつけることでクエリの変数として扱うことができる。
テンプレート(blogpost-template.js)側のクエリを、受け取った変数を使ったクエリに修正。
// src/templates/blogpost-template.js
export const query = graphql`
query($id: String!){
contentfulBlogPost(id: { eq: $id }){
title
}
}
`