Redouane Ctr

Using mdx-bundler to build a Next.js blog

Redouane Ctr
ยท
May 27, 2021

I came across MDX some months ago and ever since then I wanted to use it to make a blog (this one). I think when you're a developer, writing is a great way to cement your knowledge because it forces you to organize information, research, break down problems, and understand it enough to be able to explain it in a simple way.

I picked MDX over a CMS because it allows you to embed React components in markdown files - which is quite amazing. However, I found that the initial setup and configuration was a bit of a nightmare because there are a lot of moving parts.

Before jumping into the project, I first wanted to understand how everything fits together. So, as any developer would do, I googled it, watched a few videos, read a few articles and came to the inevitable conclusion that everyone is setting up MDX differently (the beauty of code, am I right?).

Luckily, there are a few open-source blogs like Adam Laycock, Pedro Duarte and Lee Rob that use MDX with Next.js. So I could poke around their code to try understand what was happening ๐Ÿ™. Then finally, after reading this article by Adam Laycock, things clicked (almost).

While I'm not 100% confident I completely understand everything yet and there are many things I could build upon (i.e. adding code syntax highlighting, reading time, etc), I'm confident MDX is a great way for developers to write blogs. Here's a bird's-eye view of how I think everything fits together:

  1. Path is used locate the folder where the markdown files are kept and glob is used to return an array of file paths in that folder.
  2. fs.readFileSync (a Node method) reads the file path and returns a string containing the content of each file.
  3. Then gray-matter converts front-matter (which we use to store post meta data on top of the markdown file) into an object.
  4. There are two utility functions: getAllPostsMeta() returns the meta (i.e. title, published date, etc) of all posts. getPostbySlug() returns the meta and content for a specific post.
  5. In the dynamic pages/blog/[slug].tsx page , we use getStaticPaths() to call getAllPostsMeta() and define a list of paths for Next.js to build.
  6. In getStaticProps() we call getPostbySlug() to fetch the content of an specific post and return it as props.
  7. Before displaying the post content on the page, mdx-bundler takes the markdown string and compiles it into a JSX component using bundleMDX() and getMDXComponent()
  8. Custom styling can be added to compiled JSX elements before they're rendered by creating an object that maps the element names to our own defined components. See the code here.
  9. The best way I can describe is we "intercept" the JSX component and inject our own customization by passing it to the component returned by getMDXComponent().

...and that's all for now folks. Time for some cofee. โ˜•

Built with Tailwind and Next.js ๐Ÿ–ค