• 商品一覧
  • お問合せ
  • ブログ記事
お仕事の依頼
好かれるマーケティング研究室のデフォルトサムネイル画像

Gatsbyでデータを外部から持ってきて記事を生成する

2021-11-12
前回の記事で、GatsbyでのGraphQLの使い方を学ぶことができました。
GraphQLを利用することで、プロジェクト内部のデータや外部サービスのデータに簡単にアクセスできることがわかりました。今回は、GraphQLでデータを取得して、ブログの記事ページを作成していきます。

Gatsbyでブログ記事を作成する考え方

Gatsbyでブログ記事を作成するには、2つやることがあります。1つはブログの記事を書くこと、もう1つはブログ記事のベースとなるテンプレートページを作成することです。
この2つを組み合わせることがブログ記事のページが完成します。
まずはブログ記事のファイルを作成してみましょう。

Gatsbyブログ記事用のMDXファイル作成

まずブログ記事を1箇所で管理するために、blogsフォルダを作成しておきます。srcフォルダには.jsのコードを置いているので、今回はsrcフォルダの外に配置します。
Gatsbyにblogsフォルダを追加する
ブログ記事は.mdxという形式で書きます。マークダウンを拡張して、JSXを使えるようになっている形式で、Gatsbyで使いやすい形式です。
mdxjs.com mdxjsトップページ
blogsフォルダの中に、サンプル記事としてblog1.mdx, blog2.mdx, blog3.mdxというファイルを作成します。この1つ1つのファイルが1つのブログ記事になります。
Gatsbyプロジェクトにブログ記事のファイルを追加
各ブログ記事を区別できるように以下の内容を書いておきます。
# blogs/blog1.mdx

---
title: "これは最初の記事です"
---

はじめまして!
これは僕の初めてのブログ記事です

こうやって**強調**することもできますよ。
# blogs/blog2.mdx

---
title: "2番目の記事じゃダメですか?"
---

1番目じゃなくて2番目の記事です。
# blogs/blog3.mdx

---
title: "3番目の記事は最高です!"
---

3つも記事を作ったんですか!
最後に作った記事が一番いい記事ですよね?

MDXファイルの書き方

最初の3つのハイフン("-")で区切られている箇所は、frontmatterと言います。ここには、メインのコンテンツ内容ではなく、付随する追加情報を足すことができます。
今回はタイトルを指定してブログの記事のタイトルを設定していますが、他にも日付だったり、カテゴリやタグ情報などを追加することもできます。
項目名を書いて":"で区切って、後ろにその内容を記載します。例としては以下のようになります。
---
title: "これがタイトルです"
datePublished: "2021-11-12"
author: "西松"
---
この下にはコンテンツの内容を記載しています。今回の場合は、ブログ記事の本文ですね。ここでは、markdownとJSXの記法を両方使うことができます。詳細はMDXのコンポーネント一覧を確認してください。

Gatsbyでファイル情報を取得する

gatsby-source-filesystemプラグインを使うことで、プロジェクトにあるファイルをGraphQL Data Layerに入れることができることを覚えているでしょうか。今回のようにブログ記事を作成するためには、このプラグインが必要になります。
まずはプラグインをインストールしましょう。
npm install gatsby-source-filesystem
次に、gatsby-config.jsにプラグインを利用することを伝えます。pluginsの中に、以下を追記します。
{
   resolve: "gatsby-source-filesystem",
   options: {
       name: `blogs`,
       path: `${__dirname}/blogs`,
   }
},
今回、追加でオプションを設定するので、他のプラグインと少し違った形式で追記しています。nameはクエリーで情報源をフィルターする時に使う名前になります。さらにpathでブログ記事がどのフォルダに置いてあるかを指定しています。
ここまでの内容を反映したら、一度ローカルサーバーを再起動して、プラグイン情報が反映されるようにしましょう。うまくいっていれば、GraphiQLでブログ記事の情報が取得できるはずです。
左側のExplorerから[allFile][nodes][name]を選択することで、ブログ記事のファイル名を取得できます。
query MyQuery {
 allFile(filter: {sourceInstanceName: {eq: "blogs"}}) {
   nodes {
     name
   }
 }
}
GatsbyのGraphiQLでブログ記事を表示
ここでは、sourceInstanceNameでフィルターをかけています。 これは先程オプションでnameに指定した値になります。これによって、blogsにあるファイル情報だけを取得できています。

GatsbyでMDXデータを読めるようにする

gatsby-source-filesystemでファイル情報を取得することができましたが、このままではまだGatsbyで使うことができません。MDXファイルの内容が、使いやすい形式にできないからです。
そこで、また新しいプラグインを使います。
MDXファイルを活用するためには、transformer pluginというものが必要になります。transformer pluginはファイルのデータを、GraphQL Data Layerで使いやすいように変換してくれるプラグインということになります。
gatsby-source-filesystemで取得したデータは、GraphiQLではallFileという場所にありましたね。gatsby-plugin-mdxプラグインは、allFileにある.mdx形式のデータを、allMDXという場所にデータを変換して格納してくれます。
それでは、gatsby-plugin-mdxプラグインをインストールしましょう。いくつか依存するパッケージもあるので一緒にインストールします。
npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
そして、gatsby-config.jsのpluginsにgatsby-plugin-mdxを追記します。
module.exports = {
...中略...

plugins: [
  ...中略...
  
  {
    resolve: "gatsby-source-filesystem",
    options: {
      name: `blog`,
      path: `${__dirname}/blogs`,
    }
  },
  "gatsby-plugin-mdx",
]
};
これらのプラグインの追加に成功していれば、ExplorerにallMdxとmdxのセクションが表示されるようになります。
GatsbyのGraphiQLにmdx項目を追加
せっかくGraphiQLを表示したので、このあと使うクエリもこのまま作成してしまいましょう。allMdxのデータが使えるようになりましたので、以下のようなクエリに変更します。
query{
 allMdx{
   nodes {
     frontmatter {
       title
     }
     id
     body
   }
 }
}
frontmatterで設定したブログ記事のtitle、ブログ記事ファイル固有のid、ブログ記事内容のbodyを取得します。これでMDXファイルのデータを、使いやすい形で入手することができました。
あとはこのクエリから入手したデータを、Gatsbyウェブサイトで表示するようにするだけです。

Gatsbyでブログ記事の一覧を作成する

個々のブログ記事のページを作成する前に、先程のクエリーを利用して、ブログ記事の一覧ページを作成しましょう。
src/pages内にblogsフォルダを作成し、その中にindex.jsファイルを作成します。
Gatsbyプロジェクトにブログ一覧ページを追加
このように配置するとblogs/index.jsは、http://localhost:8000/blogs/にアクセスした時の内容となります。
index.jsには先程のクエリーを利用して、タイトルを一覧にして表示します。
# src/pages/blogs/index.js

import * as React from 'react'
import Layout from '../../components/layout'
import { graphql } from 'gatsby'

const BlogPage = ( { data } ) => {

return (
  <Layout pageTitle="BlogPage">
    <h1>ブログ一覧</h1>
    <p>ここにタイトルが表示されます</p>
    <ul>
    {
      data.allMdx.nodes.map(node => (
        <li key={node.id}>
          {node.frontmatter.title}
        </li>
      ))
    }
    </ul>
  </Layout>
)
}

export const query = graphql`
query {
  allMdx{
    nodes {
      frontmatter {
        title
      }
      id
      body
    }
  }
}
`
export default BlogPage
nodesは複数形になっている通り、複数のnodeが入っています。コードでは、mapを利用することで各nodeにアクセスしています。
また、blogsフォルダを作ったことで、Layoutのインポートpathが少し変わっているので注意してください。
これを実行すると以下のようにタイトルの一覧が表示されます。(少し記事が増えていますが、気にしないでください)
Gatsbyのブログ一覧ページ

GatsbyでMDXファイルから動的にページを作成する

ブログ記事の一覧が表示されましたが、まだそれぞれの記事のページが作成されていません。
これまではページを追加するために、毎回src/pagesに.jsファイルを追加してきました。でも、ブログ記事のようにページの構成が同じであるならば、同じようなコードを何回も書くのは非効率ですよね。
今回は、MDXファイルを作成して記事を作っているので、MDXファイルを追加するだけで、ブログ記事を作れたら嬉しいですよね。
GraphQLで入手したデータ(data)の処理を行うときに{}で囲んでいたのを覚えているでしょうか?実はファイル名でもこれと同じことができます。
src/pages/blogsフォルダに{mdx.slug}.jsというファイルを作成します。そうするとGatsbyがビルドするときに各MDXファイルのslug情報を入手して、ページを自動的に作ってくれるようになります。
Gatsbyでmdxファイルからブログ記事を生成
あとはこの{mdx.slug}.jsの内容を作成すれば、ブログ記事のページが作られます。
# src/pages/blogs/[mdx.slug}.js

import * as React from 'react'
import Layout from '../../components/layout'
import { MDXRenderer } from 'gatsby-plugin-mdx'
import { graphql } from 'gatsby'

const BlogPost = ( { data } ) => {

return (
  <Layout pageTitle={data.mdx.frontmatter.title}>
    <MDXRenderer>
      {data.mdx.body}
    </MDXRenderer>
  </Layout>
)
}

export const query = graphql`
query ($id: String) {
  mdx(id: {eq: $id}) {
    frontmatter {
      title
    }
    body
  }
}
`

export default BlogPost
GraphQLではmdxファイルのIDによって、ブログ記事を区別するようにしています。クエリーにidがマッチするmdxを見つけています。
また、MDXファイルのbodyの内容を正常に表示するためには、MDXRendererを利用する必要があります。GraphiQLでbodyの中身を見るとわかりますが、複雑な形式で書かれています。その複雑な形式を処理して、本文を取り出してくれるのがMDXRendererの役目です。
import { MDXRenderer } from 'gatsby-plugin-mdx'
このファイルを作成した後に、ブラウザでアクセスするとページが表示されるようになりました。

ブログ一覧ページから個別の記事に飛べるようにする

最後にブログの一覧ページから先程作成した各ブログ記事へのリンクを貼りましょう。リンク先を入手するために、GraphQLでslugを入手するようにしました。そのslugを利用してblogs/index.jsにLinkを追加します。
# src/pages/blogs/index.js

import * as React from 'react'
import Layout from '../../components/layout'
import { Link, graphql } from 'gatsby'

const BlogPage = ( { data } ) => {

return (
  <Layout pageTitle="BlogPage">
    <h1>ブログ一覧</h1>
    <p>ここにタイトルが表示されます</p>
    <ul>
    {
      data.allMdx.nodes.map(node => (
        <li key={node.id}>
          <Link to={node.slug}>
            {node.frontmatter.title}
          </Link>
        </li>
      ))
    }
    </ul>
  </Layout>
)
}

export const query = graphql`
query {
  allMdx{
    nodes {
      frontmatter {
        title
      }
      id
      slug
    }
  }
}
`

export default BlogPage
Gatsbyのブログ一覧ページにリンクを追加
これで記事のタイトルをクリックしたら、記事のページに飛ぶようになりました。

まとめ

これでソースコードを変更しなくても、ブログ記事が制作できるようにになりました。MDXファイルを追加すればいつでもブログ記事が追加されます。
また、これと同じようにgatsby-source-XXXプラグインを利用することで、外部サービスと連携することもできます。

無料メルマガ

今すぐもっと好かれる!

プロフィール

西松 大輝:マーケティング・サイエンティスト

数字から愛へ
・「何を変えるか?」を行動経済学・TOCLSSで分析する。
・「何を伝えるか?」を戦略・マーケティングで明確にする。
・「何を測定するか?」を機械学習・ITで支援する。

"全部"やらなくっちゃあならないってのが 「マーケティング・サイエンティスト」のつらいところだな。
覚悟はいいか?僕はできてる
  • お仕事の依頼
  • お問合せ
  • プライパシーポリシー
  • 特定商取引法に基づく表記
2019-2022, 好かれるマーケティング研究室©