Search code examples
cssreactjsgatsbysanity

Problem with rich text that I get from Sanity


import React from "react"
import {
  Link,
  graphql
} from "gatsby"
import Image from "gatsby-image"
import BlockContent from "@sanity/block-content-to-react"

import Layout from "../components/layout"
import SEO from "../components/seo"

const BlogPostTemplate = ({
  data,
  location
}) => {
  const post = data.sanityPost
  const siteTitle = data.site.siteMetadata ? .title || `Title`
  const {
    previous,
    next
  } = data

  return ( <
    Layout location = {
      location
    }
    title = {
      siteTitle
    } >
    <
    SEO title = {
      post.title
    }
    description = {
      post.title
    }
    /> <
    article className = "blog-post"
    itemScope itemType = "http://schema.org/Article" >
    <
    header >
    <
    h1 itemProp = "headline" > {
      post.title
    } < /h1> <
    p > {
      post.publishedDate
    } < /p> <
    /header> <
    div >
    <
    BlockContent blocks = {
      post._rawBody
    }
    projectId = "i9vps5pu"
    dataset = "production" /
    >
    <
    /div>

    <
    div style = {
      {
        margin: "2rem 0"
      }
    } > {
      post.postImage && ( <
        Image fluid = {
          post.postImage.asset.fluid
        }
        alt = {
          post.title
        }
        />
      )
    } <
    /div> <
    hr / >
    <
    /article> <
    nav className = "blog-post-nav" >
    <
    ul style = {
      {
        display: `flex`,
        flexWrap: `wrap`,
        justifyContent: `space-between`,
        listStyle: `none`,
        padding: 0,
      }
    } >
    <
    li > {
      previous && ( <
        Link to = {
          `/${previous.slug.current}`
        }
        rel = "prev" > ←{
          previous.title
        } <
        /Link>
      )
    } <
    /li> <
    li > {
      next && ( <
        Link to = {
          `/${next.slug.current}`
        }
        rel = "next" > {
          next.title
        }→ <
        /Link>
      )
    } <
    /li> <
    /ul> <
    /nav> <
    /Layout>
  )
}

export default BlogPostTemplate

export const pageQuery = graphql `
  query NewsPostBySlug(
    $id: String!
    $previousPostId: String
    $nextPostId: String
  ) {
    site {
      siteMetadata {
        title
      }
    }
    sanityPost(_id: { eq: $id }) {
      _id
      title
      publishedDate(formatString: "MMMM DD, YYYY")
      _rawBody
      postImage {
        asset {
          fluid {
            ...GatsbySanityImageFluid
          }
        }
      }
    }
    previous: sanityPost(_id: { eq: $previousPostId }) {
      slug {
        current
      }
      title
    }
    next: sanityPost(_id: { eq: $nextPostId }) {
      slug {
        current
      }
      title
    }
  }
`

This is code is from blog-post.js file from templates folder. The main issue that I have it's the content that I get back from sanity, every text element has the expected html tag, but for some reason, the text itself ignores any styling and just spans horizontally and regardless of the page containers. I guess this non breakable space entities( ) creates this mess. What is the best way to clean that content? Thank you all in advance!


Solution

  • First of all, fix all the messy indentations, this will help to to see the structure better (in addition there are some wrong closed elements and unnecessary quotes):

    import React from 'react';
    import {
      Link,
      graphql,
    } from 'gatsby';
    import Image from 'gatsby-image';
    import BlockContent from '@sanity/block-content-to-react';
    
    import Layout from '../components/layout';
    import SEO from '../components/seo';
    
    const BlogPostTemplate = ({ data, location }) => {
      const post = data.sanityPost;
      const siteTitle = data.site.siteMetadata ? title || `Title`;
      const { previous, next } = data;
    
      return <Layout location={location} title={siteTitle}>
        <SEO title={post.title} description={post.title} />
        <article className="log-post" itemScope itemType="ttp://schema.org/Article">
          <header>
            <h1 itemProp='headline'>{post.title}</h1>
            <p> {post.publishedDate}</p>
          </header>
          <div>
            <BlockContent blocks={post._rawBody} projectId='9vps5pu' dataset='production' />
          </div>
    
          <div style={{ margin: '2rem 0' }}> {
            post.postImage && <Image fluid={post.postImage.asset.fluid} alt={post.title} />}
          </div>
          <hr />
        </article>
        <nav className='blog-post-nav'>
          <ul
            style={{ display: `flex`, flexWrap: `wrap`, justifyContent: `space-between`, listStyle: `none`, padding: 0 }}>
            <li> {previous && (<Link to={`${previous.slug.current}`} rel='prev'> ←{previous.title} </Link>)} </li>
            <li> {next && (<Link to={`/${next.slug.current}`} rel='next'> {next.title}→ </Link>)} </li>
          </ul>
        </nav>
      </Layout>;
    };
    
    export default BlogPostTemplate;
    
    export const pageQuery = graphql`
        query NewsPostBySlug(
            $id: String!
            $previousPostId: String
            $nextPostId: String
        ) {
            site {
                siteMetadata {
                    title
                }
            }
            sanityPost(_id: {eq: $id}) {
                _id
                title
                publishedDate(formatString: 'MMMM DD, YYYY')
                _rawBody
                postImage {
                    asset {
                        fluid {
                            ...GatsbySanityImageFluid
                        }
                    }
                }
            }
            previous: sanityPost(_id: {eq: $previousPostId}) {
                slug {
                    current
                }
                title
            }
            next: sanityPost(_id: {eq: $nextPostId}) {
                slug {
                    current
                }
                title
            }
        }
    `;
    

    If your wrappers (<Layout>, <article> and <div> parent of <BlockContent>) has set a defined limited max-width (or a width), the child will never span horizontally unless they are absolute positioned, which by default, it won't. A CSS rules like this should work:

    .parent-wrapper {
      max-width: 1000px;
      width: 100%;
      margin: 0 auto;
      position: relative;
    }
    
    .children {
      position: relative;
      display: inherit; // or inline-block
    }
    

    In that case, the .children will never span more than 1000px.