Reputation: 11
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.
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
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