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
:
npm 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
:
- resolve: `gatsby-transformer-remark`,
+ resolve: `gatsby-plugin-mdx`,
and plugins
with gatsbyRemarkPlugins
:
- plugins: [
+ gatsbyRemarkPlugins: [
My configured gatsby-plugin-mdx
looks like this:
// gatsby-config.js
{
// parses Markdown files using MDX
resolve: `gatsby-plugin-mdx`,
options: {
gatsbyRemarkPlugins: [
{
// parses Markdown images using Remark
resolve: `gatsby-remark-images`,
options: {
maxWidth: 1200,
},
},
],
},
},
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
:
- allMarkdownRemark {
+ allMdx {
- results.data.allMarkdownRemark.edges.forEach(({node}) => {
+ results.data.allMdx.edges.forEach(({node}) => {
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:
+ import { MDXRenderer } from 'gatsby-plugin-mdx'
Then, replace markdownRemark
with mdx
in the render()
method:
- const { markdownRemark } = this.props.data
+ const { mdx } = this.props.data
Finally, refactor the GraphQL query by using mdx
instead of markdownRemark
and body
instead of html
:
- markdownRemark(frontmatter: {
+ mdx(frontmatter: {
- html
+ body
The refactored post query will look like this:
// src/templates/postTemplate.js
export const query = graphql`
query PostQuery($slug: String!) {
mdx(frontmatter: { slug: { eq: $slug } }) {
body
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
slug
tags
}
}
}
`;
and the template component:
// src/templates/postTemplate.js
import React from "react";
import { graphql } from "gatsby";
import { MDXRenderer } from "gatsby-plugin-mdx";
import Layout from "../components/layout";
import SEO from "../components/seo";
const PostTemplate = ({
data: {
mdx: {
frontmatter: { title },
body,
},
},
}) => (
<Layout>
<SEO title={title} />
<h1>{title}</h1>
<MDXRenderer>{body}</MDXRenderer>
</Layout>
);
export default PostTemplate;
This is it! From now on, anytime you want to create a blog post, remember to use the .mdx
extension.