Gatsby supports markdown for page content out of the box and the framework is also build on top of react. The MDX format is an extension of markdown which allows jsx/tsx components to be added to the content.
Prism comes with some themes out of the box. I updated mine to a dark theme by changing the default import in gatsby-browser.js to import the tomorrow theme:
_1
import "prismjs/themes/prism-tomorrow.css";
Configure MDX
To support automatic sub-routes for blog posts or other lists (e.g. mysite.com/blog/page1), I found that the easiest structure was to have my tsx in one folder and the mdx in another:
_10
src
_10
└── content
_10
│ └── blog
_10
│ └── page1
_10
│ └── index.mdx
_10
└── pages
_10
│ └── blog
_10
│ └── index.mdx
_10
└── templates
_10
└── template1.tsx
This may be unnecessary, but other ways seemed to need a lot more configuration.
Update gatsby-config.js to point the gatsby-source-filesystem plugin to where your mdx and page files are:
gatsby-config.js
_17
plugins: [
_17
{
_17
resolve: `gatsby-source-filesystem`,
_17
options: {
_17
path: `${__dirname}/src/pages`,
_17
name: `pages`
_17
}
_17
},
_17
{
_17
resolve: `gatsby-source-filesystem`,
_17
options: {
_17
path: `${__dirname}/src/content`,
_17
name: `content`
_17
}
_17
}
_17
}
_17
]
At this point our project will support mdx, but it still needs to be added to templating.
Templating
For all post files to be passed through a template at build time, we need to configure gatsby-node.js to point all relevant files to our template file:
This will make sure that we are using the correct template for our mdx files.
I have multiple template types and mdx file containers, so I am just switching over a type property within the mdx files frontmatter and pushing to a default template if not present:
We should now have our mdx posts being rendered correctly within the correct sub-route.
Below is a demo using a simple button component that uses react hooks to increment a counter. It has been imported directly into the mdx file for this post and works as expected: