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.


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


  • 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.


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: [ 

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(
          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 }) => {

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}>


export default BlogPostTemplate

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


So far we changed:


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 Documentation ThemesGatsby Blog ThemesGatsby Portfolio ThemesGatsby Landing ThemesGatsby Free ThemesGatsby Premium ThemesGatsby Starters
Free and premium gatsby themes.
Copyright © 2019-2022 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.