GatsbyJSでサイト上のデータを任意に選んで参照し、ページに表示する


こんにちは、Gaji-Labo アシスタントエンジニアの石垣です。

先日の山岸の記事でもお伝えしましたが、この度コーポレートサイトのトップページやサービスページの内容をアップデートしました。

今回の記事ではアップデートするにあたってGatsbyJSの実装を行った際、サイト上のデータを任意に選んで参照し、ページに表示する実装を行ったため、その方法についてまとめたいと思います。

やりたかったこと

チームとプロセスの支援ページの「こんなお悩みありませんか?」

今回のアップデートで公開されたサービス詳細ページで、サービスの内容と対応したモデルケースへのリンクリストを掲載しています。

このリンクリストは直接HTMLを書いて実装することも可能ですが、GraphQLでデータを取得して流し込んだ方が全てのリンクを書く必要がなく、リンクも簡単に差し替えできるため、そのように実装しました。

対応方法

GatsbyJS 上にある Markdown ファイルの frontmatter を GraphQL で取得しました。

query {
  allMarkdownRemark(
    filter: {
      frontmatter: { type: { eq: "model-cases" }, caseId: { in: [8, 1, 6] } }
    }
  ) {
    edges {
      node {
        frontmatter {
          title
          caseId
          slug
        }
      }
    }
  }
}

frontmatter の typemodel-cases と合致するデータを参照し、なおかつ caseId を絞り込んでいます。

GraphQL の filter で in を使用すると、配列内の値に合致する全てのデータを取得することができます。

ただし取得したデータの順序は in で指定した順にはならないため注意が必要です。例の query では [8, 1, 6] となっていますが、データは昇順の [1, 6, 8] で取得されます。降順に変更することはできますが、データの順序までを任意に並び替えたい場合はこの方法だけでは対応することができません。

上の query で取得したデータは以下のようになります。

"allMarkdownRemark": {
  "edges": [
    {
      "node": {
        "frontmatter": {
          "title": "プロジェクトがうまくいっていないが、その理由がわからない",
          "caseId": 1,
          "slug": "model-case-001"
        }
      }
    },
    {
      "node": {
        "frontmatter": {
          "title": "ビジネスから開発までのプロセスがうまく繋がらない",
          "caseId": 6,
          "slug": "model-case-006"
        }
      }
    },
    {
      "node": {
        "frontmatter": {
          "title": "プロジェクトゴールへの目線合わせができていない",
          "caseId": 8,
          "slug": "model-case-008"
        }
      }
    }
  ]
}

このようにして、任意の値に合致するデータを取得することができました。

ページ上では以下のように実装しました。

const exampleData = data.example
  ? data.example.edges.map((edge) => ({
      ...edge.node.frontmatter,
      ...edge.node.fields,
    }))
  : false;

...

return (
  <ul>
    {exampleData.map((link) => (
      <li key={link.slug}>
        <Link
          to={`/case-studies/model-cases/${link.slug}`}
        >
          {link.title}
        </Link>
      </li>
    ))}
  </ul>
)

...

export const pageQuery = graphql`
  query {
    example: allMarkdownRemark(
      filter: {
        frontmatter: { type: { eq: "model-cases" }, caseId: { in: [8, 1, 6] } }
      }
      sort: { order: DESC, fields: frontmatter___caseId }
    ) {
      edges {
        node {
          id
          frontmatter {
            title
            caseId
            slug
          }
        }
      }
    }
  }
`;

これで取得したデータを使用したリンクリストが表示できるようになります。

in の値を変更することで、リンクに表示させる内容も簡単に差し替えられるようになりました。

まとめ

今回はサイトのアップデートに絡めて、GatsbyJS でサイト上のデータを任意に選んで参照し、ページに表示する実装の方法についてまとめました。

GraphQLで in を使うことで複数のデータを取得することができますが、取得したデータの順序は in では操作できない点に注意が必要です。

先日の記事にもありました通り、今後も Gaji-Labo サイトのアップデートを定期的に行っていきますのでよろしくお願いします!

Gaji-Labo は Jamstack 開発の知見があります

高パフォーマンス、表示が早く、SEO についての不安も少ない Jamstack。
フロントエンド開発の専門家として、技術選定からサーバーサイド開発側との調整まで対応します。

「Jamstack にしたいが、社内調整ができるか不安」
「Jamstack 開発がわかるエンジニアがいない」

Jamstack に関わるお困りごとに対して、メリット/デメリットの判断からお手伝いできます。
まずは一度お気軽に Gaji-Labo にご相談ください。

オンラインでのヒアリングとフルリモートでのプロセス支援にも対応しています。

フロントエンドの相談をする!

投稿者 Ishigaki Shotaro

アシスタントエンジニアとしてHTML/CSS/JavaScriptの実装やRailsの組み込み、スタイルガイドの構築などを担当しています。 業務の中でさまざまな学びを吸収しながら、文書構造やアクセシビリティに目を向けたマークアップの学習やJavaScriptの学習などを行っています。チームに貢献できるエンジニアとなるために日々奮闘中です。