Transitioning from Remark to MDX

Posted on January 27, 2019

Moving my blog from Remark to MDX.

Why?

MDX means that you can use JSX components in your markdown.

This means that blog posts down the road can have any type of content. Embed tweets, iframes without wandering around for a remark plugin, use live, editable snapshots, provide beautiful chart based visualisations, showcase some animations, bounded only by imagination (instead of remark plugins)

How?

  1. Start with installing mdx on your project with:
npm install @mdx-js/mdx @mdx-js/tag
  1. Add to it the gatsby plugin for mdx:
gatsby-mdx
  1. Add the plugin to gatsby-config.js
1plugins: [
2 {
3 resolve: `gatsby-mdx`,
4 options: {
5 defaultLayouts: { default: path.resolve('./src/components/layout.js') },
6 },
7 },
8];
  1. Change the gatsby-node page generation algorithm for mdx:

    1. Redo the query to:
{
- allMarkdownRemark {
+ allMdx {
}
  1. Getting the data from query, use:
result.data.allMdx.edges;
  1. Inside the function onCreateNode, when checking for node.internal.type:
if (node.internal.type === `Mdx`) {
  1. At the places where you get data, (the listing page and blog post page), repeat Step 2.
{
- allMarkdownRemark {
+ allMdx {
}

What about remark plugins? Can I still use them?

Sure you can. That’s the beauty.

Gatsby MDX provides an option for gatsbyRemarkPlugins to be included. You can use it like:

1options: {
2 defaultLayouts: {
3 default: path.resolve('./src/templates/blog-post.js'),
4 },
5 gatsbyRemarkPlugins: [
6 {
7 resolve: `gatsby-remark-images`,
8 options: {
9 maxWidth: 590,
10 showCaptions: true,
11 },
12 },
13 {
14 resolve: `gatsby-remark-external-links`,
15 },
16 ]
17}

Caution: It does not work with the `` format just yet. So you will always have to use an object with resolve key to put it in there.

Now, you can rename all files to mdx and restart the server.

🎉🎉 We are Done. Just like that.

Getting syntax errors in the existing blog.

I got lots and lots.

SyntaxError: unknown: Expected corresponding JSX closing tag for <img>

If you were using Github flavored markdown before, there are chances that you were embedding some JSX earlier. But the transition to MDX means that all that is going to be treated as JSX from now and rules for JSX applies.

Images are <img /> and not <img>

Once this is fixed, you can restart the server (I had to delete the cache and try too)

How is the experience so far?

Not so good. But I’m hoping for it to get better.

There were several times during this when I had to stop and start the server to have it working. Worse, there were times when deleting the cache and restarting was the only way to fix the issue.

MDX isn’t very good at errors either. If you make an import error, which you will obviously do, MDX throws a cryptic error (with bright red background) and you have to restart the server to make it go away.

The editor support is not very good. Unlike remark, there is no output directly from VS Code. You can install the MDX language support to get more syntax highlighting. But it might stop working when there is a space or tab extra. So barely working! Because of the support, writing articles becomes a pain with editor showing off unnecessary suggestions when typing.

I’m also moving from remark-prismjs to prism-react-renderer now that I can write JSX components. That has been smooth and hope to have more customisations working on how code is being shown. There has been a bug bothering me, with prism-react-renderer and mdx renderer not allowing any blank lines in between code. Currently that is hotfixed with spaces on those lines, but that is not going to be pretty to copy. Have to get that fixed.

Is there something I missed? Something wrong? Something good? Ping me on Twitter