Creating a SSG MDX Blog with React Router v7

I have been meaning to move by blog off Notion-based blog for a while. I had previously used Notion's API and Next's CMS for this. But heavy rate limiting on the Notion API and other issues made me was looking for an MDX-based, SSG friendly way to host my blog.

While we generally use NextJS for at our company. Worsening NextJS developer experience + Vercel's annoying lock-in made me decide to give React Router a try.

TL;DR

  • React Router v7 is a SSG friendly solution for creating a blog with MDX.
  • If you want to just try it yourself, fork this repo ⑂.

Why MDX?

I wanted to be able to write blog posts with markdown in my IDE, and easily preview them using Cmd+Shift+V. I had 3 other requirements:

  1. Ability to use code blocks, since a lot of my content might be code
  2. Ability to use custom React components, for dataviz and other interactive content
  3. Ability to easily move to SSR in the future, without being locked into a framework

MDX was the answer to all these requirements.

Why React Router v7?

React Router v7 is a lightweight, fast and powerful solution for creating a React sites. It used to be just a library that supported client-side navigation. But now (and with Remix features merged in) it also supports server-side rendering and excellent SEO options, which is what we need for our blog.

I wanted to avoid Vercel's lock-in, and also wanted to a SSG/SSR friendly framework that could be hosted anywhere. So I went for React Router v7.

Cool Features

Syntax Highlighting

Thanks to rehype-pretty-code I can easily add code blocks in any language. Example below:

This is a language aware code block, which means it will get syntax highlighted and rendered as a code block. I just had to start the code block with ```python and end it with ```

from openai import OpenAI
openai = OpenAI()
chat_completion = client.chat.completions.create(
    messages=[
        {
            "role": "user",
            "content": "Say this is a test",
        }
    ],
    model="gpt-4o",
)

Adding Custom Components

I can easily add custom React components to my blog posts. For example, I could add this Counter component by just adding it to my MDX file.

import Counter from "../../components/Counter";
 
# Some MDX Text
...
 
<Counter />

You can see it in action below.

You clicked 0 times

Ability to move to SSR

If the number of blog posts grow and it becomes infeasible to build them every time, it's easy to move to SSR. I can just change the vite config for certain pages to be built as SSR, by changing the prerender option in the react-router.config.ts file to ssr.

Importantly, this can be done without being locked into a platform provider like Vercel. I can just deploy the blog to any platform I want.

What's next?

I will mostly use this blog to talk about notes from implementing LLMs in enterprises, personal experiments, and other things. Might also explore some personal hobbies - but will keep self-indulgence to a minimum.