You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rich-Text-React-Renderer无法渲染h1及段落间距的问题求助

Gatsby + Contentful 富文本渲染问题解决:h1标签与段落间距不生效

问题描述

我跟着Gatsby.JS教程实现Contentful博客内容渲染,教程无需额外配置就能自动渲染h1标签及段落间距,但我的应用无法实现该效果。

Contentful内容示例:
BlogPost

我的应用渲染效果:
Rendered Post

请问需要配置哪些额外选项才能让h1标签正常渲染,并保留Contentful中设置的段落间距?

以下是我的原始代码:

import React from 'react'

import Layout from '../components/Layout'
import { graphql } from 'gatsby'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
import { renderRichText } from "gatsby-source-contentful/rich-text" 
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import Head from '../components/head'
import '../styles/global.css'

export const query = graphql`
query($slug: String!) {
    contentfulBlogPost(slug: {eq: $slug}) {
        title
        publishedDate(formatString: "MMMM Do, YYYY")
        body {
            raw
            references {
                ... on ContentfulAsset {
                    title
                    contentful_id
                    __typename
                    gatsbyImageData(width:750)
                    description
                }
            }
        }
    }
}`

const Blog = (props) => {
    const options = {
        renderNode: {
            "embedded-asset-block": (node) => {
                const { gatsbyImageData, description } = node.data.target
                if (!gatsbyImageData) {
                    // asset is not an image
                    return null
                }
                return (
                    <GatsbyImage image={getImage(gatsbyImageData)} alt={description} />
                )
            }
        }
    }

    return (
<Layout>
    <Head title={props.data.contentfulBlogPost.title} />
    <div className="blogtitlediv">
        <div className="innerblogtitlebox">
        <h1 class="text-5xl text-white text-center">{props.data.contentfulBlogPost.title}</h1>
        </div>
    </div>
   
   <div class="container py-8 px-8">
   <div class="my-10">
    {documentToReactComponents(JSON.parse(props.data.contentfulBlogPost.body.raw), options)
    &&
    renderRichText(
        props.data.contentfulBlogPost.body, options
    )}
     <p className="date" class="flex flex-row-reverse italic py-6 mx-8">{props.data.contentfulBlogPost.publishedDate}</p>
     </div>
     </div>
</Layout>
    )
}

export default Blog

解决方案

  1. 移除重复渲染方法
    你同时使用了documentToReactComponents(Contentful原生工具)和renderRichText(Gatsby封装的Contentful富文本渲染工具),这会导致渲染冲突。renderRichText能自动处理标题、段落等标签的默认渲染,只需保留它即可。

  2. 修复JSX属性错误
    JSX中需使用className替代class属性,避免样式失效。

  3. 确保全局样式未覆盖默认标签样式
    检查global.css中是否重置了h1、p等标签的margin、padding或字体样式——段落的上下间距通常由p标签的margin控制,若被重置需恢复或自定义样式。

  4. 自定义标签样式(可选)
    如果需要给富文本中的标题、段落添加自定义类名,可以在options中扩展renderNode配置,示例如下:

const options = {
  renderNode: {
    "embedded-asset-block": (node) => {
      const { gatsbyImageData, description } = node.data.target
      if (!gatsbyImageData) {
        return null
      }
      return <GatsbyImage image={getImage(gatsbyImageData)} alt={description} />
    },
    "heading-1": (node) => <h1 className="text-3xl font-bold my-4">{node.content[0].value}</h1>,
    "paragraph": (node) => <p className="my-2">{node.content[0].value}</p>
  }
}

修改后的完整代码

import React from 'react'

import Layout from '../components/Layout'
import { graphql } from 'gatsby'
import { renderRichText } from "gatsby-source-contentful/rich-text" 
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import Head from '../components/head'
import '../styles/global.css'

export const query = graphql`
query($slug: String!) {
    contentfulBlogPost(slug: {eq: $slug}) {
        title
        publishedDate(formatString: "MMMM Do, YYYY")
        body {
            raw
            references {
                ... on ContentfulAsset {
                    title
                    contentful_id
                    __typename
                    gatsbyImageData(width:750)
                    description
                }
            }
        }
    }
}`

const Blog = (props) => {
    const options = {
        renderNode: {
            "embedded-asset-block": (node) => {
                const { gatsbyImageData, description } = node.data.target
                if (!gatsbyImageData) {
                    // asset is not an image
                    return null
                }
                return (
                    <GatsbyImage image={getImage(gatsbyImageData)} alt={description} />
                )
            }
        }
    }

    return (
<Layout>
    <Head title={props.data.contentfulBlogPost.title} />
    <div className="blogtitlediv">
        <div className="innerblogtitlebox">
        <h1 className="text-5xl text-white text-center">{props.data.contentfulBlogPost.title}</h1>
        </div>
    </div>
   
   <div className="container py-8 px-8">
   <div className="my-10">
    {renderRichText(props.data.contentfulBlogPost.body, options)}
     <p className="date flex flex-row-reverse italic py-6 mx-8">{props.data.contentfulBlogPost.publishedDate}</p>
     </div>
     </div>
</Layout>
    )
}

export default Blog

内容的提问来源于stack exchange,提问作者Julius Goddard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:09:24