当サイトは、アフィリエイト広告を利用しています

【Gatsby × contentful】page生成にFileSystemRouteAPIを使う

作成日:2023月11月17日
更新日:2023年11月20日

当ブログではReactベースの静的サイトジェネレーターであるGatsbyを
使って構築しているのだが、versionをv4からv5にあげた。

そのタイミングで新機能を調べていたら、 Gatsbyにv4からの新機能である

  • FileSystem Route API

があり、実際に導入してみたので その効果や使い方をまとめえておく

Gatsbyをv5にあげる方法については下記記事でまとめています。

FileSystem Route APIとは?

ざっくりいうとファイルシステム内のファイルとディレクトリ構造を使用してウェブページの
ルーティングと生成を行うためのAPI。

ただこれだけだとイメージがつきづらいので Gatsbyのpage作成の仕組みから説明する

Gatsbyではページ生成方法

Gatsbyではページの作り方は大きく

  • src/pagesディレクトリのjsxファイルを元に静的にページを生成
  • gatsby-node.jsにcreatePagesというAPIを使って動的にページを作成

の2パターンがある。

src/pagesディレクトリのjsxファイルを元に静的ページを生成

静的なページや固定のコンテンツを表示する場合に使う。

Gatsbyは、src/pagesディレクトリにあるファイル名に基づいて
自動的にルーティングを設定してくれるので
例えば、src/pages/about.jsxというファイルを作成すれば、
/aboutというURLでアクセスできるようになる

当ブログでいうとヘッダで移動できるページは
この方法で作っている

イメージとしては下記のような感じ 2023-11-18-02-11-52 pages配下のjsxファイルからGraphQLを発行して
データを取得して静的ページを生成する

createPagesというAPIを使って動的にページを作成

外部のデータソースやMarkdownファイルなどから
コンテンツを取得して表示する場合に使う

当ブログいうと記事ページはこの方法でContentfulから
記事データを取得して作っている

イメージとしては下記のような感じ 2023-11-18-02-15-20

これが「FileSystem Route API」が導入されるv4以前
の時のpage作成の2つのパターンになる

上記の詳細については下記記事でまとめています!

目次でいうと 「src/pagesディレクトリにJavaScriptやTSXファイルを作成する」については 「記事一覧ページを作る」が該当し、

「createPagesというAPIを使って動的にページを作成する」については
「contentful取得した記事を表示する」が該当します

FileSystem Route APIを使う

FileSystem Route APIを使う場合
「gatsby-node.jsファイルにcreatePagesというAPIを使って動的にページを作成」 のパターンにおいて実装が短縮できる。

createPagesを使う場合は基本的には

  • gatsby-node.jsでcreatePagesを実装
  • テンプレートファイルを実装

する必要があるが FileSystem Route APIを使う場合は

  • src/pagesディレクトリにJavaScriptやTSXファイルを実装

で終わる。
gatsby-node.js内でgraphqlを書かなくていいし
テンプレートファイルも用意しなくてもいい。

イメージとしては下記のような感じ
2023-11-18-02-35-20

FileSystem Route APIを入れる効果

FileSystem Route APIを入れるメリットとして
下記がある

ルーティングのシンプル化

ファイルシステムルート内のファイルとディレクトリ構造に基づいて
ページのルーティングを自動的に設定する
そのためルーティングが直感的でわかりやすい。

実装の短縮

新しいページを追加するときはファイルを作成するだけなので
ファイルとディレクトリ構造を変更することでルーティングを調整できる

ビルド速度を向上

FileSystem Route APIはファイルとディレクトリの構造に基づいて
ページのルーティングとデータソースの指定を自動化する
そのため、ページの生成とデータの取得が効率的に行われ
ビルド速度が向上する。

FileSystem Route APIを使ってみる

FileSystem Route APIを使ってContentfulから
記事を取得してpageを作ってみる。

またcreatePagesとFileSystem Route APIの
作り方の違いも見てみる

環境

package.json
{
"dependencies": {
"@babel/preset-react": "^7.17.12",
"@emotion/babel-plugin": "^11.9.2",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@mdx-js/mdx": "1.6.22",
"@mdx-js/react": "1.6.22",
"dotenv": "^16.0.2",
"gatsby": "^4.14.1",
"gatsby-plugin-emotion": "^7.14.0",
"gatsby-plugin-feed": "^4.14.0",
"gatsby-plugin-gatsby-cloud": "^4.14.0",
"gatsby-plugin-google-analytics": "^4.14.0",
"gatsby-plugin-image": "^2.24.0",
"gatsby-plugin-manifest": "^4.14.0",
"gatsby-plugin-mdx": "3.20.0",
"gatsby-plugin-offline": "^5.14.1",
"gatsby-plugin-react-helmet": "^5.14.0",
"gatsby-plugin-sharp": "^4.14.1",
"gatsby-remark-copy-linked-files": "^5.14.0",
"gatsby-remark-images": "^6.14.0",
"gatsby-remark-prismjs": "^6.14.0",
"gatsby-remark-responsive-iframe": "^5.14.0",
"gatsby-remark-smartypants": "^5.14.0",
"gatsby-source-contentful": "^7.21.1",
"gatsby-source-filesystem": "^4.14.0",
"gatsby-transformer-sharp": "^4.14.0",
"prismjs": "^1.28.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-helmet": "^6.1.0",
"typeface-merriweather": "0.0.72",
"typeface-montserrat": "0.0.75"
},
"devDependencies": {
"prettier": "^2.6.2"
},
}

FileSystem Route APIを使うためには
Gatsbyがv4以上の必要がある

createPages

FileSystem Route APIを使わず、従来通り
createPagesを使った場合は下記のようになる

  • gatsby-node.js
  • templates

の二つを使って動的pageを生成する

gatsby-node.js

gatsby-node.js
const path = require(`path`)
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// contentful記事のkeyを取得
const contentfulAirticleResult = await graphql(`
query airticleQuery {
allContentfulBlogPost {
edges {
node {
slug
}
}
}
}
`)
const contentfulAirticle =
contentfulAirticleResult.data.allContentfulBlogPost.edges
//記事数分ループして記事ページを作成する
contentfulAirticle.forEach(({ node }) => {
createPage({
path: `${node.slug}/`, //記事ページのurl
component: path.resolve(`./src/templates/contentfulPost.jsx`), //記事ページ作成のtemplateコンポーネント
//templateコンポーネントに渡す引数
context: {
slug: node.slug,
},
})
})
}
  • graphqlでcontentfulからurlにするslugを取得
  • createPageでslugをurlに指定
  • createPageでtemplate(contentfulPost.jsx)を指定してpage作成

templates

contentfulPost.jsx
import React from "react"
import { graphql, Link } from "gatsby"
import MDXConvert from "../components/mdxConvert"
const ContentfulPost = ({ data }) => {
const post = data.allContentfulBlogPost.edges[0].node
const { body } = post
return (
<div>
<MDXConvert>{body.childMdx.body}</MDXConvert>
</div>
)
}
export default ContentfulPost
// gatsby-node.jsのcreatePageから渡されたslugを元にGraphQLで記事を取得
export const query = graphql`
query Query($slug: String!) {
allContentfulBlogPost(filter: { slug: { eq: $slug } }) {
edges {
node {
body {
childMdx {
tableOfContents
body
}
}
}
}
}
}
`
  • gatsby-node.jsのcreatePageから渡されたslugを元にGraphQLで記事を取得
  • 記事を描画

FileSystem Route API

FileSystem Route APIを使う場合は
src/pages`ディレクトリにjsxファイルを実装するだけで完了する

  • pages配下にjsxファイル

を1つ作って動的ページを生成する

pages/{ContentfulBlogPost.slug}.jsx

pages配下に{ContentfulBlogPost.slug}.jsxを作成する
中身はtemplate(contentfulPost.jsx)と同じになる

{ContentfulBlogPost.slug}.jsx
import React from "react"
import { graphql, Link } from "gatsby"
import MDXConvert from "../../components/mdxConvert"
const ContentfulPost = ({ data }) => {
const post = data.allContentfulBlogPost.edges[0].node
const { body } = post
return (
<div>
<MDXConvert>{body.childMdx.body}</MDXConvert>
</div>
)
}
export default ContentfulPost
// ファイル名から自動生成され実行されたGraphQLから
//渡されたslugを元にGraphQLで記事を取得
export const query = graphql`
query Query($slug: String!) {
allContentfulBlogPost(filter: { slug: { eq: $slug } }) {
edges {
node {
body {
childMdx {
tableOfContents
body
}
}
}
}
}
}
`

gatsby-nodejsのcreatePagesでslugを取得のために実行していたGraphQLが
FileSystem Route APIを使うことで自動生成されて実行され
{ContentfulBlogPost.slug}.jsxに渡される

urlはディレクトリ構造に基づいて
自動的に設定される

まとめ

FileSystem Route APIを使った方が楽にpageを作ることができた
Gatsbyは色々新しい機能がでているので
またversionをあげる際は、調べて取り込んでいきたい。

参考

新着記事

タグ別一覧
top