How to display Markdown files containing HTML syntax in Gatsby?

685 Views Asked by At

I am using Markdown file to generate pages for gatby. In order to control the style of pictures, I use html syntax. However, the page generated by gatsby does not display the html part.

This is my markdown file:

---
......frontmatter......
--- 
......content......
<table>
  <tr>
    <td><img src="./images/2018/zotero/ZoteroWebDAV.png"></td>
    <td><img src="./images/2018/zotero/ZoteroExts.png" width=100%></td>
  </tr>
</table>
......content......

Everything else is rendered normally, however, neither the table nor the pictures in it are displayed. Here is my gatsby-config.js.

{
      resolve: `gatsby-transformer-remark`,
      options: {
        excerpt_separator: `<!-- endexcerpt -->`,
        plugins: [
          // 'gatsby-remark-relative-images',
          {
            resolve: `gatsby-remark-images`,
            options: {
              maxWidth: 1200,
            },
          },
          {
            resolve: `gatsby-remark-image-attributes`,
            options: {
              dataAttributes: true
            }
          },
        ],
      },
    },

What can I do to make the html part in Markdown render normally?

1

There are 1 best solutions below

0
On BEST ANSWER

You can use as well the built-in dangerouslySetInnerHtml property or any markdown parser like markdown-to-jsx.

Using the first approach, following Gatsby's guides:

import React from "react"
import { graphql } from "gatsby"

export default function Template({data}) {
  const { markdownRemark } = data // data.markdownRemark holds your post data
  const { frontmatter, html } = markdownRemark
  return (
    <div className="blog-post-container">
      <div className="blog-post">
        <h1>{frontmatter.title}</h1>
        <h2>{frontmatter.date}</h2>
        <div
          className="blog-post-content"
          dangerouslySetInnerHTML={{ __html: html }}
        />
      </div>
    </div>
  )
}

export const pageQuery = graphql`
  query($id: String!) {
    markdownRemark(id: { eq: $id }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        slug
        title
      }
    }
  }
`

Because you haven't shared your query I've used the one in the guide but tweak it as you wish. As you can see, everything that is in the end of the frontmatter is html:

<div
  className="blog-post-content"
  dangerouslySetInnerHTML={{ __html: html }}
/>

Using the second approach, and following the previous query structure, the html should be rendered as:

import Markdown from 'markdown-to-jsx';
import React from 'react';

<Markdown>{html}</Markdown>

If there's any hindrance I'd say that the second approach is better because, as the dangerouslySetInnerHTML name suggests, you are potentially exposing your site to XSS (Cross-Site Scripting), while the second approach sanitizes the implementation.