Processing markdown in Gatsby with Contentful

May 28, 2020

reactjs
markdown
blog
gatsbyjs

There are two most common ways of using markdown in Gatsby with a headless CMS tool.

This post will present how to use them with Contentful service. Additionally it will include contenful image converter inside markdown.

gatsby-remark-images-contentful

Amazing plugin for converting and optimaizing images from contentful into Gatsby blog.

$ npm install gatsby-remark-images-contentful

gatsby-plugin-mdx

This is a very popular plugin mostly used for processing markdown and them placing it into the HTML. It is also usefull if you want not only process markdown but also include your own JSX components.

Adding markdown content from CMS in Gatsby blog

  1. Install plugin
$ npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
  1. Add plugin into gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-mdx`,
      options: {
        gatsbyRemarkPlugins: [
          {
            resolve: `gatsby-remark-images-contentful`,
            options: {
              maxWidth: 590,
              linkImagesToOriginal: false,
              withWebp: true,
              loading: "lazy",
            },
          },
        ],
      },
    },
  ]
}
  1. Add markdown text field into Contentful Content Type.
  • Add field
  • Select Text field (Long text, full-text search)
  • In configuration select Markdown

Contentful markdown gatsby converter

  1. In your blog post template graphql query get markdown body
export const query = graphql`
    contentfulBlogPost(slug: { eq: $slug }) {
      title
      body {
        childMdx {
          body
        }
      }
    }
`
  1. Use markdown in blog post template component
import React from "react"
import MDXRenderer from "gatsby-plugin-mdx/mdx-renderer"
import { MDXProvider } from "@mdx-js/react"

const BlogPostTemplate = ({data}) => {
  const blogData = data.contentfulBlogPos
  
  return (
    <MDXProvider>
      <h1>{blogData.title}</h1>
      <article className={classes.article}>
        <MDXRenderer>{blogData.body.childMdx.body}</MDXRenderer>
      </article
    </MDXProvider>
  )
}
  1. From now on you can put your imports and React components inside Contentful markdown field. It will be automatically detected and transformed.

gatsby-transformer-remark

Plugin powered by remark processor. It parses markdown but without included parser for React components.

  1. Install plugin
npm install --save gatsby-transformer-remark
  1. Add plugin into gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images-contentful`,
            options: {
              maxWidth: 590,
              linkImagesToOriginal: false,
              withWebp: true,
              loading: "lazy",
            },
          },
        ],
      },
    },
  ]
}
  1. Add markdown field in Contentful Content Type of your blog as in previous plugin description

  2. In your blog post template graphql query get markdown body

export const query = graphql`
    contentfulBlogPost(slug: { eq: $slug }) {
      title
      body {
        childMarkdownRemark {
          html
        }
      }
    }
`
  1. Use markdown in blog post template component
import React from "react"
import MDXRenderer from "gatsby-plugin-mdx/mdx-renderer"
import { MDXProvider } from "@mdx-js/react"

const BlogPostTemplate = ({data}) => {
  const blogData = data.contentfulBlogPos
  
  return (
    <>
      <h1>{blogData.title}</h1>
      <div
        dangerouslySetInnerHTML={{
          __html: blogData.body.childMarkdownRemark.html,
        }}
      ></div>
    </>
  )
  1. If you want to use custom components inside markdown you need to use additional plugin gatsby-remark-component with rehype-react which is also very simple. Full description how to do it can be found in linked documentation.

Summary

It is your choice which plugin you will use. I have tried both and currenly I'm using gatsby-plugin-mdx for markdown processor including custom component.

I'm also very happy with plugin for simple image optimization gatsby-remark-images-contentful. If you are looking for low cost and simple image optimalization for your blog, this is it!

Built with love to Python logo React logo Gatsby logo ยท Piotr Rogulski