Today I added support for writing posts with MDX - a mixed way to write with Markdown + React syntax and generate the HTML pages. The rendering looks the same, yet it's very different underneath now.

Do I Need MDX?

When I first created this site with Gatsby, I ignored the template which already came with MDX enabled. What I did was to stick with .md - just Markdown with the basic support with HTML.
What I was thinking was that: when would I even need React in the post? Probably never.

I was SO Wrong

As I gained more techiniques with React, I start thinking to add more fun stuff in the post. For example, I want to make the link style consistent. I have made a progress bar like link for the site (Try hover your mouse on the "a process" link top left) and I want to apply it for links in the post too!
Most importantly, MDX makes repeating things easier, in a world that software engineers should avoid repeat, MDX is preferred.

But it is not easy, the gatsby-plugin-remark generates the html completely, I didn't find a good way to override it. So I turned back to MDX and it cost me two nights to debug and recreate the post part of this website.

Apparently it's switched now, try hover your mouse on the link below:

Pretty cool.

By the way this is the old one I had:

Steps to Migrate from .md to .mdx

  1. First install the gatsby-plugin-mdx, via
npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react
  1. In the gatsby-config.js, replace the gatsby-trasnformer-remark with the new MDX plugin, as follows:
  {
    resolve: `gatsby-plugin-mdx`,
    options: {
      extensions: [`.mdx`, `.md`],
      gatsbyRemarkPlugins: [
      ... // your previous remark plugins
      ],
    },
  },

One thing you will notice is that I make both .md and .mdx to be treated as capable for MDX, so I don't need to rename my existing files.
Another fancy part is to change the plugins field to gatsbyRemarkPlugins and most of the gatsby-transformer-remark will just work.

  1. Replace the node generation
    This basically means change all the GraphQL queries from allMarkdownRemark to allMdx.
NOTE

What I learned from the Gatsby doc is to create a file named .js to generate the route of all the files. As I tried, it is convenient for simple use cases, which I'd encourage you to do if it applies to yours.

However, to support other features, such add a post navigation, or have a more consolidated way to manage the templates, I think adding the page generation logic in gatsby-node.js is the better choice.

  1. The caveat part
    4.1 One thing is quite tricky is about the slug generated. MarkdownRemark generates with a root, i.e., /foo/bar/file/path/ while the MDX plugin generates as foo/bar/file/path, so be cautious with such a difference.

    4.2 The slug is the next field of the node. To be specific, before the slug is accessed as node.fields.slug, now it becomes node.slug. To make the code work for your case, my suggestion is to use the GraphQL tool (http://localhost:8000/___graphql) to inspect.

  2. Modify the CSS settings
    The way MDX renders the content is using a MDXRenderer, which renders the body (a bunch of human hardly readable characters but essential for MDX to render), therefore the final content is a bit different

Now you should be all done.

What I Learned

This is really a good recap for myself to learn more about the GraphQL, as I'm feeling rusty for not using it for a while. MDX definitely can provide more capability for me in the future to produce better content (and more beautiful). For example a small React app would be very cool!

Overall I was just interested and curious, then why not just try it?