Gatsby+contentfulでRichTextのjsonが見当たらない...


状況

リッチテキストを扱うためにgraphqlでbodyのjsonを取得したいが、データが無いといわれる

pages/index.jsx

import { documentToReactComponents } from "@contentful/rich-text-react-renderer"

export default ({ data }) => {
  return (
    {documentToReactComponents(data.contentfulBlogPost.content.json)}
  )}

export const query = graphql`
  query {
    contentfulBlogPost {
      title
      content {
        json <-これが無い!!!!!!!
      }
    }
  }
`

gatsby-source-contentful v4

2020/11/9にRichText関連の大きなアップデート、BREAKING CHANGES(互換性を破る変更)があったようです。

・Refactor Rich Text implementation in gatsby-source-contentful (#25249) (a256346), closes #25249 #24221
BREAKING CHANGES
This major release improves Contentful's Richtext experience. If you are not using the Rich Text Contentful field type there are no breaking changes.

詳しくはリリースノートを確認ください。
https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-source-contentful/CHANGELOG.md#400-next0-2020-11-09

変更点

今回関係ありそうなのは以下の通り

Use the raw subfield instead of json

  • jsonの代わりにrowを使ってね

To render Rich Text fields use the new renderRichText() function from gatsby-source-contentful/rich-text

  • gatsby-source-contentful/rich-textrenderRichText()をRichTextの描画に使ってね

簡単なサンプル

基本的にはdocumentToReactComponentsと使い方は同じ
引数はrowまでは参照しないように注意
基本的にはrich-text-react-rendererのラッパーのようですね
https://github.com/contentful/rich-text/tree/master/packages/rich-text-react-renderer

index.jsx

import { renderRichText } from "gatsby-source-contentful/rich-text"

export default ({ data }) => {
  return (
    <p>{data.contentfulBlogPost.title}</p>
    {renderRichText(data.contentfulBlogPost.content⭕️, {})}
  // renderRichText(data.contentfulBlogPost.content.raw❌, option)
  )}

// graphql
export const query = graphql`
  query {
    contentfulBlogPost {
      title
      content {
        raw
      }
    }
  }

まとめ

ほかにもrichTextの体験が向上しているそうなので詳しくはGithubのリリースノートをご確認ください。
公式ドキュメントがまだ追いついてないらしいので、日本語での情報も探すの大変だとおもいます。。

とは言ったものの、issueを読み漁って見るとわかりますが、なんなら公式のreadmeも間違っている箇所があるみたい。

気が向いたら別記事にv4でのリッチテキストの詳細をまとめたいところですが、
実際どれくらいの人がこの記事を見ているかわからないので、モチベーションが正直ないです。

余談

これでjsonにしても問題なさそう

JSON.parse(data.contentfulBlogPost.content.raw)

画像が表示されない問題

公式のissueにて画像が表示されない場合の対応が書かれていました。

https://github.com/gatsbyjs/gatsby/discussions/28098
__typenameと追加しないとrawの中にある"nodeType": "embedded-asset-block"の画像の参照が解決されないようです。

index.jsx
export const query = graphql`
query{
  body {
        raw
        references {
          ... on ContentfulAsset {
            contentful_id
            __typename
            file {
              url
            }
          }
        }
      }
    }
`