Published 26/03/2024

Use MDX with Next.js to create your own blog

I have used strapi, a CMS, to host my blog content. However, I was looking for an easier solution that did not involve hosting a service on the cloud. As the only writer for my blog, I did not need a platform for writers to access publicly. and I currently have no plans for external platforms or services to consume the data. Hence, I was looking for a simple offline solution that could still allow me to write my content but without the hassle of maintaining the CMS

I found documentation in next.js stating that it supports markdown and generates static html files from markdown. I also came across a tool to manage my content directly on vscode. frontmatter, is a CMS built directly in the vscode as an extension, you can view and manage the content you wrote directly. sort of similar to how a traditional CMS would work.

Different solutions to content management

A modern CMS like strapi can provide multiple clients with a centralized service to retrieve the content. These clients can be a mobile app, a web page or another backend system that consumes data. Whereas, static generated markdown file to HTML approach eliminates the need for a server as the new html files are published together when the code is compiled. It can be during a build pipeline like in Next.js static site generation that content is pulled down and published into an html file. Or it can be dynamic content that is updated frequently and served to clients all over the world in real-time. Whatever you choose there is a solution.

For my decision, I found that using the offline approach would fulfill my current needs and it wouldn't cost me any money to run my blog website. For personal websites or blogs, this approach is much simpler. But if it were to scale to many writers and many different clients that need to consume this data, a CMS would definitely be a better solution.

clientCMSweb serverbuild pipelineclientCMSweb serverbuild pipelinealt[static generation][dynamic content]alt[content as a markdown file][content hosted on CMS]transform MD to HTMLupload as static files to hostget contentreturn contentupload as static files to host asGets data in real time as the page is visited by the userreturns the up-to-date dataComparision Between Markdown and CMS

Install the packages

First, install the following packages needed to parse the markdown in Next.js

# basic packages for next.js to parse MD into HTML
npm install @next/mdx @mdx-js/loader @mdx-js/react

# plugins to transform markdown and html
npm install rehype-mermaid remark-frontmatter remark-gfm remark-mdx-frontmatter

Setup config file

Next, add create a next.config.mjs file and add it to root if you already haven

You can add the following configuration as I have below. There are several plugins I have added to make writing content in markdown much easier.

  1. add support for .mdx file extensions, which allows me to use jsx in markdown.
  2. add frontmatter so that we can add metadata to our markdown and use it to customize the metadata of the html page for better SEO.
  3. add Github flavored markdown(Gfm) for functionalities like tables or links.
  4. add Mermaid capability which allows users to draw diagrams with code
import createMDX from '@next/mdx'
import remarkFrontmatter from 'remark-frontmatter'
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
import rehypeMermaid from 'rehype-mermaid'
import remarkGfm from 'remark-gfm'

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Configure `pageExtensions` to include MDX files
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
  // Optionally, add any other Next.js config below
}

const withMDX = createMDX({
  // Add markdown plugins here, as desired
  extension: /\.mdx?$/,
  options: {
    remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm],
    rehypePlugins: [rehypeMermaid],
  },
})

export default withMDX(nextConfig)

Create a file and write

Create a .mdx file in your pages or app folder under any directory path. As I am still using Page router in next.js, I would be placing it in a folder structure as such

root of app
|-next.config.mjs // config file
|-pages
|--|blog
|----|-my-first-post.mdx // markdown content

You can write your content like how you would in a typical markdown file

# My title

## some sub header

some content goes here

Next.js will autocompile the markdown and output the file as html. There you have it!

markdown is rendered as html markdown rendered as html

So with this simple setup you will be able to write your blog and publish to your website in no time. In the next article, i would be setting up some useful custom mdx components and also show how to integrate with frontmatter to manage your content better.

More documentation about the various terms and topics mentioned in the post below:

Tag
cmsfrontmattermdxmermaidnext.jsstrapimarkdown
Categories
Technology
contact: work[at]jianhowe.com