June 30, 2025 • 3 min read

How I'm Using Notion as My Blog CMS

I’ve always liked the idea of writing blog posts in a clean, distraction-free editor. Notion was already where I kept most of my notes, so it felt natural to turn it into a mini CMS for my personal website.

Instead of using a bunch of .md files or a headless CMS like Sanity or Contentful, I set up a simple Notion database — and it works surprisingly well.

My Notion Setup

In my Notion workspace, I created a page called Blog, and inside it, I added an inline database called blog database.

Each post is just a row in that table, with three properties:

  • title — the post title
  • slug — a short text identifier for the URL
  • published — a checkbox so I can hide drafts

The actual content of each post is written directly in the Notion page using markdown blocks. No embeds, no rich text, just pure markdown. Super clean.

The Integration

On the code side, I’m using:

  • @notionhq/client — to fetch pages from the Notion API

    import { Client } from "@notionhq/client";
    
    const notion = new Client({ auth: process.env.NOTION_TOKEN })
    
    export async function getPublishedPosts() {
      const response = await notion.databases.query({
        database_id: process.env.NOTION_DATABASE_ID!,
        filter: {
          property: "published",
          checkbox: { equals: true },
        },
        sorts: [
          {
            timestamp: "last_edited_time",
            direction: "descending",
          },
        ],
      });
    
      return response.results;
    }
    
  • notion-to-md — to convert Notion blocks into actual markdown

    import { NotionToMarkdown } from "notion-to-md";
    
    export const n2m = new NotionToMarkdown({ notionClient: notion });
    
    export async function getPostMarkdown(pageId: string) {
      const mdBlocks = await n2m.pageToMarkdown(pageId);
      return n2m.toMarkdownString(mdBlocks);
    }
    
  • MDXRemote — to render the markdown on the frontend

Once I get the markdown content, I pipe it through my MDX setup (with Next.js App Router), and style it using Tailwind’s prose classes. It looks good, reads clean, and just works.

Why This Works for Me

This setup is simple, lightweight, and easy to maintain. I don’t need to push changes to GitHub every time I want to write something. I just open Notion, write a post, check the “published” box, and it's live.

No CMS dashboards, no complicated content workflows. Just Notion and some solid open source tools.

Looking Ahead

At some point, I might add features like tags, categories, or reading time. But for now, I’m just happy I can finally write in Notion and have it show up on my site automatically.

If you’re reading this in the future — hey, this is where it all started.