Convert an existing Gatsby Markdown blog to use MDX
I've recently released a new version of my personal website and I decided to convert my posts from an existing Gatsby Markdown format to MDX.
MDX is usually called the markdown for the component era and it's a great way to write a document using JSX in Markdown. Additionally, if you work on a React project, you can even import existing components inside your MDX files.
Let's get started!
Step 1
In order to use MDX with Gatsby, you need to install @mdx-js/mdx
, @mdx-js/react
and the official Gatsby plugin gatsby-plugin-mdx
:
1npm install --save @mdx-js/mdx @mdx-js/react gatsby-plugin-mdx
Step 2
Inside your gatsby-config.js
file, replace gatsby-transformer-remark
with gatsby-plugin-mdx
:
1- resolve: `gatsby-transformer-remark`,2+ resolve: `gatsby-plugin-mdx`,
and plugins
with gatsbyRemarkPlugins
:
1- plugins: [2+ gatsbyRemarkPlugins: [
My cofigured gatsby-plugin-mdx
looks like this:
1{2 // parses Markdown files using MDX3 resolve: `gatsby-plugin-mdx`,4 options: {5 gatsbyRemarkPlugins: [6 {7 // parses Markdown images using Remark8 resolve: `gatsby-remark-images`,9 options: {10 maxWidth: 1200,11 },12 },13 ],14 },15},
For reference, here is my entire gatsby-config file.
Step 3
Once we've refactored the gatsby-config.js
file, it's time to work with gatsby-node.js
.
Here, we need to replace allMarkdownRemark
with allMdx
:
1- allMarkdownRemark {2+ allMdx {
1- results.data.allMarkdownRemark.edges.forEach(({node}) => {2+ results.data.allMdx.edges.forEach(({node}) => {
My gatsby-node.js
file is available over here.
Step 4
The final step consists in refactoring the template file that is used to generate the blog posts.
Head over to the template, in my case src/templates/postTemplate.js
, and import MDXRenderer
from the gatsby-plugin-mdx
plugin that we installed earlier:
1+ import { MDXRenderer } from 'gatsby-plugin-mdx'
Then, replace markdownRemark
with mdx
in the render()
method:
1- const { markdownRemark } = this.props.data2+ const { mdx } = this.props.data
Finally, refactor the GraphQL query by using mdx
instead of markdownRemark
and body
instead of html
:
1- markdownRemark(frontmatter: {2+ mdx(frontmatter: {
1- html2+ body
The refactored post query will look like this:
1export const query = graphql`2 query PostQuery($slug: String!) {3 mdx(frontmatter: { slug: { eq: $slug } }) {4 body5 frontmatter {6 title7 date(formatString: "MMMM DD, YYYY")8 slug9 tags10 }11 }12 }13`;
and the template component:
1import React from 'react';2import { graphql } from 'gatsby';3import { MDXRenderer } from 'gatsby-plugin-mdx';45import Layout from '../components/layout';6import SEO from '../components/seo';78const PostTemplate = ({9 data: {10 mdx: {11 frontmatter: { title },12 body,13 },14 },15}) => (16 <Layout>17 <SEO title={title} />18 <h1>{title}</h1>19 <MDXRenderer>{body}</MDXRenderer>20 </Layout>21);2223export default PostTemplate;
For reference, here is my entire postTemplate
component.
This is it! From now on, anytime you want to create a blog post, remember to use the .mdx
extension.