1. home
  2. blog
  3. how to convert existing gatsby markdown blog to mdx

How to convert existing Gatsby markdown blog to mdx

September 29, 2019

What is MDX?

It’s like “JSX in markdown”. It lets you seamlessly write code in JSX in your markdown blog posts, for example.


Pros:

  • Declarative, more straightforward concept
  • Frontmatter and props support
  • All power of markdown with power of react components

Cons:

  • Non-informative error messages
  • Need to restart development server after each added/changed import component
  • Broken preview in vscode, github, gitlab(even with plugin)

Yes, it has some disadvantages. But nevertheless, I think mdx is the “new markdown”. All these problems are temporary, and since it really cutting-edge technology, having all those problems are absolutely natural. And if it’s not production-ready yet, for personal blog or site it’s absolute killer.

Guide

So, are you ready to discover future of tech blogging?
If you have no blog yet, just use gatsby-starter-blog-mdx, it has mdx support out of the box. Also you can check out official docs.
And for those who already have a blog and want to touch the awesomness of mdx, I will cover in details how to convert your markdown blog to mdx, let’s go.

Check out files in this repo as an example

  1. Install all dependencies:
npm i gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react

Optionally, add eslint mdx plugin:

npm i -D eslint-plugin-mdx
  1. Update Gatsby lifecycle files:

In gatsby-config, scroll to gatsby-transformer-remark, and replace:

gatsby-transformer-remark -> gatsby-plugin-mdx plugins -> gatsbyRemarkPlugins

using following example:

module.exports = {
  plugins: [
      ...
          {
      // line below changed
      resolve: `gatsby-plugin-mdx`, 
      options: {
        // line below changed
        gatsbyRemarkPlugins: [ 
          ....
          `gatsby-remark-smartypants`,
        ],
      },
    },
  ]
}

In gatsby-node, in GraphQL query replace “allMarkdownRemark” with “allMdx”, and “MarkdownRemark” with “Mdx”, so it will look like this:

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions

  const blogPost = path.resolve(`./src/templates/blog-post.js`)
  const result = await graphql(
    `
      {
        allMdx(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: 1000
        ) {
          edges {
            node {
                ...
    `
 const posts = result.data.allMdx.edges
                ...

if (node.internal.type === `Mdx`) {
    const value = createFilePath({ node, getNode })
    ...
  }
...
  1. Update post listing generation

In index.js(or where your posts listed), replace all “allMarkdownRemark” with “allMdx”:

class BlogIndex extends React.Component {
  render() {
    const { data } = this.props
    const posts = data.allMdx.edges

    return (
      <Layout location={this.props.location}>
        <SEO title="All posts" />
        <Bio />
        {posts.map(({ node }) => {
          ...
        })}
      </Layout>
    )
  }
}

export default BlogIndex

export const pageQuery = graphql`
  query {
    allMdx(sort: { fields: [frontmatter___date], order: DESC }) {
      edges {
        ...
      }
    }
  }
`
  1. Update blog post template

In your /src/templates/blog-post.js (or similar), you need to do following changes:

  • add import MDXRenderer
  • replace dangerouslySetInnerHTML with MDXRenderer
  • update query(change “markdown” to “mdx” and “html” to “body”)
import { MDXRenderer } from 'gatsby-plugin-mdx';

class BlogPostTemplate extends React.Component {
  render() {
    const post = this.props.data.mdx
    return (
      <Layout title={post.frontmatter.title}>
        <ContentSection
          title={post.frontmatter.title}
          subtitle={post.frontmatter.date}
          color="white"
          size="medium"
        >
          <article>

            <MDXRenderer>{post.body}</MDXRenderer>

            ....
    )
  }
}
export default BlogPostTemplate

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    mdx(fields: { slug: { eq: $slug } }) {
      id
      excerpt(pruneLength: 160)
      body
      frontmatter {
      ...
      }
    }
  }
`
  1. rename all your .md files to .mdx
  1. restart your development server:
gatsby develop

Conclusion

So far we changed:

gatsby-config
gatsby-node
blog-post.js
index.js(page)


Congratulations! you now have working mdx blog. Stay tuned.


Subscribe for updates

Join 100+ subscribers and get news about
themes, releases and special offers

Relative posts:

Gatsby Blog ThemesGatsby Documentation ThemesGatsby Portfolio ThemesGatsby Landing ThemesGatsby Free ThemesGatsby Premium ThemesGatsby Starters
GatsbyTemplates.
Free and premium gatsby themes.
TwitterYouTube
Copyright © 2021 GatsbyTemplates.io. By using this site, you’re agreeing to our Terms of Service and Privacy Policy. We are listing free and premium templates. Terms of Service and technical support only applies to premium templates that were made by GatsbyTemplates team.