Professional Documents
Culture Documents
js and MDX
When I decided to build my blog, I found many tools out there that were readily available. I
looked at Gastby along with content management systems like Ghost, Contentful, Sanity dot io,
and HUGO.
But I needed something that I could have total control over. I've also always been someone who
loves the flexibility of writing own my custom code. When I do this, I can conveniently go back
to where any issues might be when a problem arises.
Gatsby provides this flexibility, and it is something I could get familiar with pretty easily since
it's built on a library I use every day (React.js). But, I found out that I can do the exact same
thing with Next.js by integrating MDX.
Well... MDX is more or less like the markdown files we always see in GitHub repositories.
MDX brings this flexibility into a markdown file by allowing you to literally write or import
JavaScript (React) components into your articles. This in turn saves you from writing repetitive
code.
In this article, I am going to show you how I built my blog with these tools, so you can also try
building something similar. You'll like this simple stack if you are a person who loves the
flexibility that this approach brings.
They are:
At first, I started by using Kent's mdx-bundler, but then I ran into a lot of problems with the tool.
It is a library that is based on the new ECMAScript standards that allow us to create ESModules
in the browser, and I was using a very old version of Next.js (V10.1.3, my bad honestly, I didn't
know any better).
I did a lot of downgrading and upgrading of Next.js to fix this problem to no avail. There was a
certain error that stuck with me, and refused to go away for days. Yes, for days! I felt like crying
during that period. Take a look at the error below:
Apparently, for mdx-bundler to work, it needs another npm package called esbuild to do the
necessary compiling processes that work under the hood.
Luckily for me — at least I thought I was lucky — Cody Brunner submitted an issue about this
particular error. Going through the discussions on the issue, a lot of possible fixes were
suggested, some of them were related to Webpack, modifying your next.config.js file, and
whatnot.
module.exports = {
future: {
// Opt-in to webpack@5
webpack5: true,
},
reactStrictMode: true,
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
if (!isServer) {
// https://github.com/vercel/next.js/issues/7755
config.resolve = {
...config.resolve,
fallback: {
...config.resolve.fallback,
child_process: false,
fs: false,
'builtin-modules': false,
worker_threads: false,
},
}
}
return config
},
}
In the snippet above, it shows that Webpack5 was still a feature that was in progress for Next.js –
hence the snippet below in the config:
future: {
webpack5: true
}
But, now the latest version of Next.js supports Webpack5 by default, so there's no need to add
that object — if it works for you — in the config.
After going through the discussions, I found a comment (by Kent) that says running npm update
would fix the issue, and it did work for Cody Brunner. But not for me apparently.
When I couldn't find a possible fix to this error, I decided to use next-mdx-remote, and the only
issue I faced was the breaking change that was added to the tool. Before version 3 of next-mdx-
remote you would normally render parsed markdown content by doing the following:
return {
props: {
source: mdxSource,
},
}
}
The breaking change that was added in version 3 of the package stripped off a lot of internal
code that was perceived to cause poor experiences for people who were using it at that time.
The team went on to announce the reason behind this change and the major changes. Take a look
at them below.
This release includes a full rewrite of the internals of next-mdx-remote to make it faster, lighter-
weight, and behave more predictably! The migration should be fairly quick for most use-cases,
but it will require some manual changes. Thanks to our community for testing out this release
and providing early feedback. heart.
With this new change, the previous implementation will now become:
import { serialize } from 'next-mdx-remote/serialize'
import { MDXRemote } from 'next-mdx-remote'
return {
props: {
source: mdxSource,
},
}
}
In this section, we're going to cover how you can build a similar blog like mine.
The command above will give you a boilerplate of a typical Next.js app. For the sake of brevity,
I'll be focusing more on the pages and src/utils folders of this app.
|--pages
| |-- blog
| | |-- index.js
| | |-- [slug].js
| |-- _app.js
| |-- index.js
|--src
| |-- utils
| |-- mdx.js
|--data
| |-- articles
| |-- example-post.mdx
| |-- example-post2.mdx
In a typical blog, we'd need to write blog posts or articles. In this blog, we're using markdown
(MDX) to write our articles, which is why you can see that we have two .mdx files inside the
data/articles directory. You can have more than that, as far as the number of articles you
want to write goes.