Migrating Remark to MDX

For people who already have an existing blog using gatsby-transformer-remark but want to use MDX, you can swap out the Remark transformer plugin with gatsby-plugin-mdx and touch little code otherwise.

Prerequisites

  • An existing Gatsby site that builds pages using gatsby-transformer-remark (gatsby-starter-blog will be used as a reference in this guide)

Adding in gatsby-plugin-mdx

Add the gatsby-plugin-mdx plugin (and its peer dependencies) to your package.json file and remove the gatsby-transformer-remark plugin.

Replacing gatsby-transformer-remark with gatsby-plugin-mdx

In your gatsby-config.js file, replace gatsby-transformer-remark with gatsby-plugin-mdx. Most sub-plugins of gatsby-transformer-remark can still work with gatsby-plugin-mdx by updating the plugins option to gatsbyRemarkPlugins.

Update file extensions

Where your Markdown files live, changing their individual file extensions from .md to .mdx will pick them up with the new configuration.

Alternatively, you can tell gatsby-plugin-mdx to accept both .md and .mdx files by adding the extensions option in your gatsby-config.js entry.

Now with this addition, gatsby-plugin-mdx will see files that end with both .mdx or .md.

Update gatsby-node.js

In the createPages API call, when you query for allMarkdownRemark, replace it with allMdx.

Don’t forget to update the posts constant by replacing allMarkdownRemark with allMdx.

Also, update onCreateNode which creates the blog post slugs to watch for the node type of Mdx instead of MarkdownRemark.

Update usage in pages

Similar to gatsby-node.js, wherever you use allMarkdownRemark in a GraphQL query, change it to allMdx.

Then in your blogpost template, to render the MDX, pull in the MDXRenderer React component from gatsby-plugin-mdx.

And in the GraphQL query, change the html field in mdx to body.

And finally swap out the component with dangerouslySetInnerHTML to a MDXRenderer component:

Update Markdown files that include HTML code

As MDX uses JSX instead of HTML, examine anywhere you put in HTML and make sure that it is valid JSX. There might be some reserved words that need to be modified, or attributes to convert to camelCase.

For instance, any HTML component with the class attribute needs to be changed to className.

Additional resources