Migrating from .md to .mdx files in Gatsby

by Hannah Goodridge ~ 1 min read

I recently migrated my content over from plain markdown files to MDX files because I wanted to harness the power of using react components in some of my blog posts.

MDX is a superset of Markdown. It allows you to write JSX inside markdown. This includes importing and rendering React components!

Getting to it

First off I converted my .md files to .mdx.

I then updated my gatsby-config.js to use:

  {
    resolve: `gatsby-source-filesystem`,
    options: {
      name: `content`,
      path: `${__dirname}/src/content`,
    },
  },
  {
    resolve: 'gatsby-plugin-page-creator',
    options: {
      path: `${__dirname}/src/content`,
    },
  },
  {
    resolve: 'gatsby-plugin-mdx',
    options: {
      extensions: ['.mdx', '.md'],
    },
  }

Removing any gatsby-transformer-remark plugins along the way.

Notice that I've had to add the path to my content folder where I keep my content pages.

In order to process and use Markdown or MDX in Gatsby, you can use the gatsby-source-filesystem plugin.

The gatsby-plugin-page-creator is optional but I need it becuase here I'm creating additional “pages” so want to override the default usage.

In your component import the following:

  import { MDXProvider } from '@mdx-js/react';
  import { MDXRenderer } from 'gatsby-plugin-mdx';

and


  const { body, frontmatter } = mdx;
  return (

    <article>
      <MDXProvider components={[myComponent]}>
        <MDXRenderer>{body}</MDXRenderer>
      </MDXProvider>
    </article>
  );

Here you can see I am passing myComponent to the MDXProvider, all MDX components passed into the components prop of the MDXProvider will be made available to MDX documents that are nested under the provider.

My graphql query inside the page has to pull in the body data from my mdx graphql query.

The graphql looks like:

export const myQuery = graphql`
  query() {
    mdx() {
      body
      frontmatter {
        slug
        title
      }
    }
  }
`;

The contents of my .mdx files look something like this:

  ---
  title: "my title"
  slug: "posts/my-blog-post"
  ---
  ### this is the body of the .mdx file

  import { myComponent } from "../components/myComponent"

  <myComponent text="some text" />

The frontmatter needs to appear at the top of the file and then imports/content can follow.

In the gatsby docs it states you can pass the frontmatter data to the jsx component like this if thats something you want to do:

  <MDXRenderer frontmatter={post.frontmatter}>{post.body}</MDXRenderer>
---
title: Hello World
---

<p>{props.frontmatter.title}</p>

!Important

For now, this only works if the .mdx file exporting the query is placed in src/pages.

Updating gatsby node and graphql queries

Switch your allMarkdownRemark or markdownRemark graphql queries in your app for allMdx or mdx

And thats that!