Gatsby Source Contentful 4.x — форматированный текст — переход на JSON

Я пытаюсь получить форматированный текст из Contentful, но в версии 4.x gatsby-source-contentful документация больше не обновляется. Он ссылается на json, но он изменился на raw, а значит, я не знаю, как действовать дальше.

Это мой код:

import React from "react"
import { graphql, Link } from "gatsby"
import { documentToReactComponents } from "@contentful/rich-text-react-renderer"

import Layout from "../components/layout/layout"
import Img from "gatsby-image"
import SEO from "../components/layout/seo"

export const query = graphql`
  query($slug: String!) {
    contentfulBlogPost(slug: { eq: $slug }) {
      title
      publishedDate(formatString: "Do MMMM, YYYY")
      featuredImage {
        fluid(maxWidth: 750) {
          ...GatsbyContentfulFluid
        }
      }
      body {
        json
      }
    }
  }
`

const BlogPost = props => {
  const options = {
    renderNode: {
      "embedded-asset-block": node => {
        const alt = node.data.target.fields.title["en-US"]
        const url = node.data.target.fields.file["en-US"].url
        return <img alt = {alt} src = {url} />
      },
    },
  }

  return (
    <Layout>
      <SEO title = {props.data.contentfulBlogPost.title} />
      <Link to = "/blog/">Visit the Blog Page</Link>
      <div className = "content">
        ...
        {props.data.contentfulBlogPost.featuredImage && (
          <Img
            className = "featured"
            fluid = {props.data.contentfulBlogPost.featuredImage.fluid}
            alt = {props.data.contentfulBlogPost.title}
          />
        )}
        {documentToReactComponents(
          props.data.contentfulBlogPost.body.json,
          options
        )}
      </div>
    </Layout>
  )
}

export default BlogPost

Если вы посмотрите на раздел ниже, я считаю, что здесь что-то не так. Сообщение об ошибке, которое я получаю: «Не удается запросить поле «json» для типа «ContentfulBlogPostBody».», Но если я изменю его на необработанное вместо json, оно не даст мне никаких ошибок, но тогда оно не отображается форматированный текст (тело):

 }
      body {
        json
      }
    }
  }
`

Ниже приведен скриншот того, как модель контента настроена в Contentful:

Contentful - модель контента

Как мне использовать более новую версию gatsby-source-contentful (в настоящее время это версия 4.2.1) с изменением способа обработки форматированного текста?

🤔 А знаете ли вы, что...
React использует компонентную архитектуру для организации кода.


5
2 254
1

Ответ:

Решено

Вы можете найти пример использования rawв документации gatsby-source-contentful.

Вот как может выглядеть запрос с использованием форматированного текста:

{
  allContentfulBlogPost {
    edges {
      node {
        bodyRichText {
          raw
          references {
            ... on ContentfulAsset {
              contentful_id
              __typename
              fixed(width: 1600) {
                width
                height
                src
                srcSet
              }
            }
            ... on ContentfulBlogPost {
              contentful_id
              __typename
              title
              slug
            }
          }
        }
      }
    }
  }
}

И вы можете использовать его так.

import { BLOCKS, MARKS } from "@contentful/rich-text-types"
import { renderRichText } from "gatsby-source-contentful/rich-text"

const Bold = ({ children }) => <span className = "bold">{children}</span>
const Text = ({ children }) => <p className = "align-center">{children}</p>

const options = {
  renderMark: {
    [MARKS.BOLD]: text => <Bold>{text}</Bold>,
  },
  renderNode: {
    [BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,
    [BLOCKS.EMBEDDED_ASSET]: node => {
      return (
        <>
          <h2>Embedded Asset</h2>
          <pre>
            <code>{JSON.stringify(node, null, 2)}</code>
          </pre>
        </>
      )
    },
  },
}

function BlogPostTemplate({ data, pageContext }) {
  const { bodyRichText } = data.contentfulBlogPost

  return <div>{bodyRichText && renderRichText(bodyRichText, options)}</div>
}