Eduards Birznieks
Eduards Birznieks

Reputation: 11

Formatting markdown HTML data in a Gatsby component using static-query

I am trying to display html information form a markdown file using a component with a static query in GatsbyJS. When I print the data I get raw HTML with the tags.

Curent result

I would like to display the title of the markdown and the HTML text underneath.

components/contact.js

    import React from "react"
import { Link, StaticQuery, graphql } from "gatsby"

const Cont = ({ data }) => (
  <section className="home-banner">
    <h1 className="title">
      {data}
    </h1>
    <div className="description">
      {data}
    </div>
  </section>
)

export default function ContText() {
  return(
    <StaticQuery
      query={graphql`
        query MyQuery {
          markdownRemark(frontmatter: {template: {eq: "contact-page"}}) {
            html
            frontmatter {
              title
            }
          }
        }`
      }

      render={ data  => {

        return(
          <Cont

                data={data.markdownRemark.html}

          />
        )
       }
      }
    />
  )
}

Is there a way that I can display the title and text using one component and how can I change raw HTML to cleaner text data like in normal pages.

 index-page.js

import React from "react"
import { graphql, Link } from "gatsby"
import Img from "gatsby-image"

import Layout from "../components/layout"
import BlogListHome from "../components/blog-list-home"
import SEO from "../components/seo"
import Cont from "../components/contact"

export const pageQuery = graphql`
  query HomeQuery($id: String!){
        markdownRemark(id: { eq: $id }) {
      id
      html
      frontmatter {
        title
        tagline
        featuredImage {
          childImageSharp {
            fluid(maxWidth: 480, maxHeight: 380, quality: 80, srcSetBreakpoints: [960, 1440]) {
              ...GatsbyImageSharpFluid
            }
            sizes {
              src
            }
          }
        }
        cta {
          ctaText
          ctaLink
        }
      }
    }
  }
  `

const HomePage = ({ data }) => {
  const { markdownRemark } = data // data.markdownRemark holds your post data
  const { frontmatter, html } = markdownRemark
  const Image = frontmatter.featuredImage ? frontmatter.featuredImage.childImageSharp.fluid : ""
    return (
        <Layout>
      <SEO/>
      <div className="home-banner grids col-1 sm-2">
        <div>
          <h1 class="title">{frontmatter.title}</h1>
          <p class="tagline">{frontmatter.tagline}</p>
          <div className="description" dangerouslySetInnerHTML={{__html: html}}/>
        </div>
        <div>
          {Image ? (
            <Img
              fluid={Image}
              alt={frontmatter.title + ' - Featured image'}
              className="featured-image"
            />
          ) : ""}
        </div>
      </div>
      <div>
      <Cont/>
      </div>
      <BlogListHome/>
      <div>
      <h1> Recomendations go hear!</h1>
      </div>
        </Layout>
    )
}

export default HomePage

Currently, I am thinking of creat 2 components one for the tittle one foe the content but It won't matter, if I cant, change the HTML. Thank you all in advance.

Upvotes: 1

Views: 1805

Answers (1)

Ferran Buireu
Ferran Buireu

Reputation: 29320

You are retrieving your data correctly. Your GraphQL looks good and gather all data from the markdown file properly.

What are you missing is a dangerouslySetInnerHTML in your HTML tag. dangerouslySetInnerHTML is a React's replacement for using innerHTML in the browser DOM. So, applied to your code:

<h1 className="title" dangerouslySetInnerHTML={{ __html: data }} />

Note: same applies to the <div>. Because you are not wrapping anything inside, you can self-close your <h1>

The naming comes because generally, could be risky because it exposes your users to a cross-site scripting (XSS) attack. Ideally, you should map each response of data and render one parsed tag or another depending on it but for now, as in 95% of the cases, it will work as expected without any risk exposure for the users.

You can check for further information at React's official documentation.

Upvotes: 2

Related Questions