首页 > 解决方案 > 无法使用 Gatsby.js 从 Contentful headless cms 正确呈现富文本字段

问题描述

所以,我正在为当地企业建立一个网站,他们可以使用内容丰富的 cms(有点像以前工作的博客)添加以前的工作(它是一种翻新类型的业务)。

我遇到的问题是我需要显示在内容丰富的文本字段中定义的每个作业的内容。

我将向您展示我的项目组件(这是一个通过 gatsby create pages api 创建页面的模板),它是:

    import React from 'react';
    import { graphql } from 'gatsby';
    import { documentToReactComponents } from "@contentful/rich-text-react-renderer"
    import { BLOCKS } from "@contentful/rich-text-types"
    import Layout from '../components/layout';
    
    
    const Project = ({data}) => {
        const RichContent = JSON.parse(data.contentfulProject.projectContent.raw);
        const options = {
            renderNode: {
                [BLOCKS.HEADING_1]: (node, children) => <h1>{children}</h1>,
                // [BLOCKS.EMBEDDED_ASSET]:  <img src={`https:${data.contentfulProject.projectContent.references.fluid.src}`}/>,
            },
        renderMark: {},
        }
        console.log(data)
        return (
            <Layout>
                
                {documentToReactComponents(RichContent, options)}
            </Layout>
        )
    }
    
    export default Project;
    
    export const query = graphql`
        query($id: String!) {
            contentfulProject(id: {eq: $id}) {
                    title
                    projectContent  {
                        raw
                        references {
                                fluid {
                                        src
                                        
                                    }
                            }
                        }
                    }
                }
    `

所以实际上我设法成功地呈现了文本字段,但是当我取消注释 [BLOCKS.EMBEDED_ASSET] 时,由于缺少数据而导致分页符。图像不显示。

我的猜测是在查询内容数据时我无法访问 json 字段,我只得到原始字段。

请帮忙 :D


设法解决了这个问题,这里是正确显示图像的工作组件的代码:

import React from 'react'
import { graphql } from 'gatsby';
import { renderRichText } from "gatsby-source-contentful/rich-text"
import { BLOCKS } from "@contentful/rich-text-types"

import Layout from '../components/layout'


function ProjectTemplate({ data }) {
  const {projectContent} = data.contentfulProject
  console.log(projectContent)

  const options = {
    renderMark: {},
    renderNode: {
      [BLOCKS.PARAGRAPH]: (node, children) => <p>{children}</p>,
      [BLOCKS.EMBEDDED_ASSET]: node => {
        return (
            <img src={`https:${node.data.target.fixed.src}`}/>
        )
      },
    },
  }

  return (
    <div>
      <Layout>
      {renderRichText(projectContent, options)}
      </Layout>
    </div>
  )
}

export default ProjectTemplate

export const query = graphql`
  query($id: String!) {
    contentfulProject(id: {eq: $id}) {
                contentful_id
                title
                slug
              projectContent {           
                raw
                references {
                  ... on ContentfulAsset {
                    contentful_id
                    __typename
                    fixed(width: 1600) {
                      width
                      height
                      src
                      srcSet
                    }
                  }
                }
              }
            }
          }
`

标签: graphqlgatsbycontentfulrichtext

解决方案


使用一些结构,如:

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>
        </>
      )
    },
  },
}
​
renderRichText(node.bodyRichText, options)

每种类型的字段都有自己的renderNode,这使您可以灵活地使用自己的组件来呈现和设置数据样式。

由于BLOCKS.EMBEDDED_ASSET您的代码没有返回任何内容,使用上面的代码段,您可以自定义输出,如果需要绕过它,则返回一个空对象。


推荐阅读