Gatsby Content from MDX

In a previous post we looked at how to use AsciiDoc Markdown to author content for a Gatsby site. Another approach to handling Markdown content is MDX, which is “Markdown for the component era”. In this post we’ll see how to integrate MDX into a Gatsby site.

⚠️ We’ll be using the gatsby-plugin-mdx plugin. There are breaking changes between older and newer versions of this package and we’ll consider both.

🚀 TL;DR This post references two distinct demo sites: (1) using the old API (the code is on the 28-mdx branch) and (2) using the new API (the code is on the 29-mdx-updated branch).

Old API

Install Package

Add gatsby-plugin-mdx as a dependency in package.json. You’ll need to tweak the versions of other packages to make everything consistent. Update dependencies. 🚨 We’ll start by using version 3.20.0 of the gatsby-plugin-mdx. The API has changed with later versions of the package and you need to take a different approach to integrating MDX content. 🌲 This code is on the 28-mdx branch.

Configure

Now you need to update gatsby-config.js. In the simplest case you just need to add "gatsby-plugin-mdx" to the list of plugins. There are a number of package options which you can specify too.

Add a "gatsby-source-filesystem" entry to make the folder containing your .mdx files available.

Add Content

Now add some MDX content. We’ll create a file, content/home.mdx, with some simple content that will be pulled through into the landing page. In the YAML header specify type: landing. We’ll use this to filter out the data for this specific file.

GraphQL

At this stage you can build the site and take a look at the GraphQL Explorer. You’ll see that there are two new categories:

  • allMdx and
  • mdx.

The first is to access the data for all of the .mdx documents and the second to get data for specific individual .mdx documents.

Add a GraphQL query to src/templates/home.js that pulls in data for content/home.mdx by filtering on type.

Render MDX

Finally in the component for the landing page include the MDX content using the <MDXRenderer> component.

Landing page generated with old API with content from MDX.

New API

🚨 Now we’ll update to a more recent version of the gatsby-plugin-mdx package that uses the new API. Modify package.json accordingly. 🌲 This code is on the 29-mdx-updated branch.

Update Create Pages

We need to update gatsby-node.js, passing the __contentFilePath parameter along with the component parameter and specifying the path to the MDX file. The plugin will automatically process the specified MDX file and pass it to the template as children. Now in the template file we need to replace

<div>
  <MDXRenderer>{data.mdx.body}</MDXRenderer>
</div>

with

<div>
  {children}
</div>
Landing page generated with new API with content from MDX.

Changing to TypeScript

I also changed this branch to use TypeScript. These are the specific changes made:

  • Add a tsconfig.json file.
  • Rename src/templates/home.jsx to src/templates/home.tsx.
  • Modify the IndexPage component so that it’s valid TypeScript.

Conclusion

This is a very high level overview of how to get MDX content into your Gatsby site. The biggest challenges I encountered when putting this together were:

  1. figuring out what version of the gatsby-plugin-mdx plugin to use in order to access the gatsby-plugin-mdx component and
  2. finding a set of other packages that was consistent with that plugin version.

The way that you pass the MDX content to the template differs depending on whether you are using the old or new API.