ITエンジニアの種籾(たねもみ)

IT技術とか株式投資とか。

Gatsby.js で json データを読もう

2020年 07月 22日

目次

Gatsby.js でブログサイトのメタ情報を json で管理するために、 データソースとして json ファイルを扱えるようにします。

Gatsby.js でブログサイトを作りました。 この仕組はローカルファイルシステムの Markdown をデータソースとして、ブログサイトをビルドするものです。

Gatsby.js で作ったブログサイトのメニューや記事に付与するタグの情報をどう実装するか考えるときに、 React コンポーネントのソース上に定数で直書きするのは良くないです。

そこで、Markdown だけではなく、json もデータソースとして扱えるようにしてみます。

Gatsby.js で扱うデータのおさらい

Gatsby.js でデータを扱う場合は以下の2つのプラグインを使います。

  • データソースプラグイン : ファイルや DB などのリソースを加工する対象の土台に乗せる。
  • トランスフォーマープラグイン : Markdown や json などデータの種類に応じて GraphQL で扱うデータに変換する。

2つの意味わからない人は、【Gatsby.js チュートリアルを読んでみよう】または、 本家サイトのGatsby.js Tutorials を読み直してください。

ただし、難しい仕組みじゃないので、このページだけ読んでも理解できると思います。

json のためのデータソースプラグイン

今回、メニューやタグなどのメタデータは、ローカルの json ファイルで管理しようと思います。

なので、ファイルシステムを扱うので、データソースプラグインは Markdown と同じ gatsby-source-filesystem です。

ファイル格納場所

メニューやタグの json ファイルは記事の Markdown とはフォルダで管理することにします。

こんなフォルダ構成です。

フォルダ構成

データソースプラグインの設定

では、データソースプラグインの設定をしてみて、GraphQL で確認してみます。 とりあえずは中身が空のファイルをmenu.jsontags.jsonの2つ作りました。

プラグインの設定は、gatsby-config.jsにあり、以下を追加します。

plugins: [
  {
    resolve: `gatsby-source-filesystem`,
    options: {
      path: `${__dirname}/../crz33-contents/metadata`,
      name: `blog`,
    },
  },
];

データソースに追加されたことを確かめる

GraphiQL でファイルが追加されているか確かめてみましょう。

URL は

http://localhost:8000/___graphql

です。

まだ、データソースに追加しただけなので、ファイルとして取得できるようになっただけです。

GraphQL は

query MyQuery {
  allFile {
    edges {
      node {
        base
      }
    }
  }
}

で、クエリしてみると、以下のように 2 つの json が追加されました。

ファイルクエリ

トランスフォーマープラグインを使う際の json の書き方

json のトランスフォーマープラグインはgatsby-transformer-jsonです。 gatsby-transformer-json に説明があります。

説明を読むと、json の中身とファイルの単位にルールがあります。

  • ファイルの中身が配列 : 1 つのファイルでノード群に変換する
  • ファイルの中身がオブジェクト : 複数ファイルを結合してノード群に変換する

複数ファイル対応として、オブジェクト型があるのだと思いますが、 普通に使うレベルであれば、ファイルをわけずに配列で書けばいいです。

わかりやすいメニューの json を作ります。

menu.jsonをこんな感じで作ってみました。

[
  {
    "name": "TOP",
    "url": "/"
  },
  {
    "name": "Gatsbyブログ",
    "url": "/gatsby-blog/"
  }
]

トランスフォーマープラグインのインストールと設定

本題のgatsby-transformer-jsonプラグインです。

ますはパッケージをインストールします。

[~/workspace/crz33-gatsby] $ npm install --save gatsby-transformer-json

プラグインの設定は gatsby-config.js に以下を追加するだけです。

plugins: [
  {
    `gatsby-transformer-json`,
  }
]

これでデータソースに json があれば、パースして GraphQL で扱えるデータに変換してくれます。

json が変換されているか確かめる

GraphiQL でファイルが追加されているか確かめてみましょう。

URL はデータソースと同じく、

http://localhost:8000/___graphql

です。

GraphiQL で見てみると、allMenuJson が追加されています。 GraphQL でクエリすると、json の中身が返ってきました。

json

これで、ブログサイトのコンポーネントから json の中身をクエリして使える準備ができました。

コンポーネントからアクセスしてメニューを作ってみる

ここからは惰性なので、詳しくは説明しませんが、クエリできるようになった json からメニューを作るための実装します。

メニューはサイトのヘッダコンポーネントに書いてあるので、そこでクエリしてループ回します。 クエリには Static クエリパターンを使います。

ヘッダコンポーネントの全ソースはステップ数が多いので載せずに、クエリと使用箇所だけ抜粋します。 CSS フレームワークである Bulma を使っており、className に書いてあるのは Bulma の Menu コンテナのクラスです。

TODO github にプッシュしたら、ここにリンクを貼ります。

const SiteHeader = () => {
  // クエリ
  const staticData = useStaticQuery(graphql`
    query HeaderQuery {
      allMenuJson {
        edges {
          node {
            name
            url
          }
        }
      }
    }
  `)
  // クエリの結果から配列を取り出す
  const menuItems = staticData.allMenuJson.edges

  // 省略

          // ループしてリンクを作る
          <div id="navbarSiteMenu" className="navbar-menu">
            <div className="navbar-start">
              {menuItems.map(({ node }) => {
                return (
                  <Link to={node.url} className="navbar-item">
                    {node.name}
                  </Link>
                )
              })}
            </div>
            <div className="navbar-end"></div>
          </div>

これで、サイトの上部にあるメニューを json から生成できるようになりました。

メニュー

以上です。

広告