Posted December 17th, 2019 by Zack Spellman
In which we add technology for technology's sake.
As is my usual habit, once I've upgraded something I cannot resist continuously tweaking with it until I get bored. In doing so, I frequently fail to actually use the technology I setup, which leads me to wonder why I did it in the first place. But no matter that now, we've added more technlogy!
Behold, a trivial Todo app inside a blog post!
How amazing is this? Right? I guess? Maybe I should explain what's happening here.
Last time I mentioned that I was writing my blog posts in Markdown instead
of raw html. This is a huge quality of life improvement - pressing enter is a
lot simpler than ensuring my <p>
tags are matched. But like all abstractions,
the simplicity comes at the cost of expressiveness.
As I read more about Gastby, it became clear that a Markdown extension called MDX was the hot hotness these days, and I wanted to give it a try. What MDX allows you to do is to interleave React components with standard Markdown, so that you can have custom-made things appear instead of just text, headings, and images (I'm underselling Markdown a bit).
I read quite a few articles while trying to figure out how to convert my remark-based gatsby blog to an mdx-based blog, but as with most programming it was a fair bit of combining sources and guesswork which allowed me to get this setup just right. My primary sources were:
Now, you can just skip to the good part and look at my diff, but the slightly longer version is:
Add your dependencies with npm
or yarn
:
gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
Update gatsby-config.js
gatsby-transformer-remark
for gatsby-plugin-mdx
plugins
to gatsbyRemarkPlugins
Update gatsby-node.js
's onCreateNode()
handler
node.internal.type
, Swap MarkdownRemark
for Mdx
Update your static GraphQL queries
allMarkdownRemark
for allMdx
markdownRemark
for mdx
html
for body
Update your templates
<div dangerouslySetInnerHTML={{ __html: post.html }} />
<MDXRenderer>{post.body}</MDXRenderer>
import { MDXRenderer } from 'gatsby-plugin-mdx';
Once you've done these few mechanical changes, you can try out MDX in your very own markdown files! For example, to get the TodoApp earlier in the article, the beginning of this post looks like:
import TodoApp from './TodoApp';
Behold, a trivial Todo app _inside_ a blog post!
<TodoApp initialTodos={['Create Todos']} />
The only other thing I did to support my new capabilities was to install syntax highlighting for my editor (VSCode), since MDX is still new enough that it isn't supported right out of the box.
Now, it turns out installing MDX was trivial compared to actually building the Todo App I created to show off the new features. I spent an evening setting up MDX, but getting the Todo App into a publishable state took another three or four evenings. So my next post will be about building that sucker - where the code was inspired by, why I didn't just use it as-is, and how bad I really am at CSS. But for now, I hope this post helps someone shortcut their gatsby upgrade to MDX, and they don't get nearly as distracted as I did actually using it.