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:
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:
src
└── content
│ └── blog
│ └── page1
│ └── index.mdx
└── pages
│ └── blog
│ └── index.mdx
└── templates
└── 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
plugins: [
{
resolve:`gatsby-source-filesystem`,
options: {
path:`${__dirname}/src/pages`,
name:`pages`
}
},
{
resolve:`gatsby-source-filesystem`,
options: {
path:`${__dirname}/src/content`,
name:`content`
}
}
}
]
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: