PR
【GatsbyJS製ブログ】ページを作るcreatePageの仕組みを理解する
Gatsbyでは、サイトをビルドする際に、gatsby-node.jsと言われるJSファイルで色々な情報を取得しながらページを作っていきます。
そのなかでも実際にページを作るcreatePageについてまとめていきます。
今回はcreatePageの使い方の確認&まとめの健忘録記事です。
createPageとは
createPageはテンプレートからページを作成するAPIです。
テンプレートは、例えばブログ記事やタグページの大枠のようなもの、と思ってもらえたらOKです。これにcreatePageで、それぞれのページの内容を渡すことで実際にページを作っていきます。
ですので、実際にはgatsby-node.js内でGraphQLを使ってデータ取得→必要なデータ加工をしてcreatePageに渡してページ作成、という流れになります。
具体的には、次のような形でcreatePageを使います。
createPage({
path: "(作るページのパス)",
component: path.resolve(`(ページ作成のためのテンプレートファイルのパス)`),
context: {
(↑のテンプレートファイルへ渡すprops)
},
})
createPageの構造は結構シンプルです。
pathは作るページのパスです。もちろん個別に入力しても構いませんが、そんなことをしていたらGatsbyの機能が泣いてしまいます。先ほど言ったように、GraphQLで必要な情報を引っ張ってきて、加工して渡すのがセオリーです。
componentは上記の形で作りたいテンプレートファイルのパスを指定してあげます。
一番重要なのはcontextです。
ここで指定した値は、受け取り側のテンプレートにpageContextとして渡っていきます。
そして、ここで渡した値は、渡した先のテンプレート内でGraphQLの条件指定などに変数として使えます。
GraphQLのフィルターで変数を使いたいときは、このcreatePageのcontextで渡すしかないです。
ちょっと話がわかりにくくなってきたので、gatsby-starter-blogのソースでどのようにcreatePageが使われているか見てみましょう。
…
const blogPost = path.resolve(`./src/templates/blog-post.js`) //あらかじめ「blogPost」にブログ記事のテンプレートを入れとく
…
const result = await graphql(` //GraphQLでマークダウンのidとslugを取得
{
allMarkdownRemark(sort: { frontmatter: { date: ASC } }, limit: 1000) {
nodes {
id
fields {
slug
}
}
}
}
`)
…
const posts = result.data.allMarkdownRemark.nodes //postsにGraphQLのnode情報だけ入れとく
if (posts.length > 0) {
posts.forEach((post, index) => {
const previousPostId = index === 0 ? null : posts[index - 1].id
//↑ここは前の投稿のIDを取得するロジック。前の投稿のIDを取得してテンプレートに渡すことで、よくある「前の記事」のリンクに使う。
const nextPostId = index === posts.length - 1 ? null : posts[index + 1].id
//↑同様に次の投稿のIDを取得する。
createPage({
path: post.fields.slug, //pathはGraphQLから取得したslugから作る
component: blogPost, //あらかじめ入れておいたテンプレートのパスをこのような形でも指定できる。
context: {
id: post.id, //各記事のIDが個別に渡される
previousPostId, //その記事の前のID
nextPostId, //その記事の次のID
},
})
})
}
}
…
…
export const pageQuery = graphql`
query BlogPostBySlug(
$id: String! //こんな感じでcontextからもらった値を…
$previousPostId: String //同上
$nextPostId: String //同上
) {
site {
siteMetadata {
title
}
}
markdownRemark(id: { eq: $id }) { //フィルターの条件として使える
id
excerpt(pruneLength: 160)
html
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
description
}
}
previous: markdownRemark(id: { eq: $previousPostId }) { //これも同じ
fields {
slug
}
frontmatter {
title
}
}
next: markdownRemark(id: { eq: $nextPostId }) { //これも同じ
fields {
slug
}
frontmatter {
title
}
}
}
`
こんな感じでテンプレート側のGraphQLでcontextの値を使えるのが最大の特徴です。
これによって、テンプレート側でピンポイントでブログ記事の内容、タイトル、ディスクリプション、etc..を拾ってくることができます。
もちろん、contextで渡した値はpageContextとして直接propsに入ってくるので、GraphQLだけじゃなくテンプレート側のpropsとして扱えます。
まとめ
createPageについての説明でした。
Gatsbyのページ作成における基本ですが、GraphQLも含めて、Gatsbyの構造がわかっていないとちょっと何をしているかわかりにくい部分です。
特に、contextがテンプレートにpropsとGraphQLのフィルターで使える変数として渡っていく、というイメージを持っておくと、テンプレートも思い通りに加工しやすくなります。
このへんがGatsby特有の振る舞いですので、押さえておきましょう。
Gatsbyを学習している方への私からのオススメ!
私が読んでよかったな、と思うGatsbyの学習をするのにオススメの本を紹介しておきます。
画も多くてとても読みやすく、ステップバイステップでGatsbyJSのサイトを作ることができます!
また、Gatsbyを学習する上で、Reactを同時に学習することもオススメします。
こちらも、まず構成や見た目がとても読みやすい本です。加えてReactに対しての専門的な知識を丁寧に学ぶことができます。ここでReactに対する基礎知識をしっかりしておくと、Gatsbyに対する見方が変わって、Webページをサクサク作ることができるようになります!
あと、色々と調べたのですが、Reactの学習ならUdemyもオススメです。必要な知識を1動画単位で購入できるので、学習に無駄がないです。Reactってあんまり学習できるプログラミングスクールみたいなのがないんですよね…。「React」と検索するだけで大量に動画がでてきます!