How-To Build An MDX Powered Blog In Next.js With next-mdx-remote

November - 2021

TL;DR:

I just moved my site to Next.js. I was using mdx-bundler for MDX functionality, but kept having problems with it. The official @mdx-js/loader for webpack looked like a good replacement, but wasn't. It shows frontmatter in the content instead of processing it as data. So, I ended up switching to next-mdx-remote.

Here's the final details of the process with more details below. There are only three (pages/index.js and pages/posts/[slug].js)

Final Setup

Initial commands (using alanwsmith.com as the example)

mkdir alanwsmith.com
cd alanwsmith.com
npx create-next-app .
npm i next-mdx-remote gray-matter
mkdir _posts
rm -rf pages/api

pages/index.js

TKTKTKT: pages/posts/[slug].js

TKTKTKT: components/ExampleComponent.js

TKTKTK: _posts/*.mdx

Notes

  • I'm a fan of minimal examples/tutorials. I've removed everything I can here to get to the core of how to use the next-mdx-remote module. Consider this a starter and season to taste.

  • I run my site no Netlify. Version 4 of their plugin is beta. Once it's out, you can just do @netlify/plugin-nextjs

  • next-mdx-remote doesn't allow you to create components or data in the .mdx files themselves. That sucks, but I'll take the compromise compared to having to setup another process to deal with yaml frontmatter in @mdx-js/loader. (Though, frontmatter gets sorted out in @mdx-js/loader I'll switch since being able to write your components in the mdx files is really pretty fundamental)

  • I find CSS gets in the way of my brain trying to learn things that aren't CSS so there's no styling here.

  • The path to the _posts directory is hard coded in a few places. This duplication could be removed, but it's minimal enough that I'm not bothered by it and abstracting it would complicate the example.

  • I spent some time working with the compile option from @mdx-js/mdx. I could split out the frontmatter with gray-matter and only process the contents of the file but I haven't figure out how to actually render the result. If I can solve that, it's what I'll switch to.

  • I run this on netlify, to do that, I add this npm i @netlify/plugin-nextjs@4.0.0-beta.9. And then test locally with netlify dev instead of npm run dev

  • https://next-mdx-remote-blog-example.netlify.app/


Netlify devply

  • set Publish directory to .next