How to build a blog on your portfolio website using Notion
A long time ago, I used to write blogs on Medium. While it is a incredibly popular platform, I found it highly frustrating. It was difficult to style posts the way I wanted, and the writing environment came with too many limitations. If you’ve ever tried publishing technical stories there, you probably know the feeling.
Everything changed when I stumbled upon a Youtube video by the Kodaps Academy channel. The creator had built a notion-parse plugin and combined it with Contentlayer. Although both of those projects are no longer actively maintained, the underlying concept was brilliant. Inspired by this, I forked his project and tailored it to my own needs.
On June 18, 2026, I updated the functions to support the latest Notion database types and comments. Recently, I also added a major feature: native support for the Next.js MDX format. This has been an absolute lifesaver since I built most of my projects with Next.js, which supports MDX out of the box. Thanks to this workflow, I have fully transitioned to writing my blogs in Notion — and this very post is the first one built using this new setup!
How it works
First off, you can find my open-source project on npmjs. I am committed to keeping it updated with the latest Notion features and API changes.
The tool currently offers two modes:
- Standard Markdown Mode: Generate classic
.mdfiles - Next.js MDX Folder Mode: Generate
.mdxfiles
Note: MDX mode is only available from version 1.1.0 onward and is currently in the experimental stage.
You can find detailed installation and usage instructions on the github repository or npm page, but I wanted to highlight a few key setup requirements here.
To get the Next.js MDX Folder Mode up and running, you must create an mdx-components.tsx file (as recommended by the official Next.js documentation). This file is required to make @next/mdx work.
First install the necessary dependency:
# npm install
npm i @next/mdx
Then, you can use a configuration similar to mine:
// ./mdx-components.tsx
import Image, { type ImageProps } from 'next/image'
import { type MDXComponents } from 'mdx/types'
export function useMDXComponents(components: MDXComponents) {
return {
...components,
Image: (props: ImageProps) => <Image {...props} />,
}
}
And that’s it! The only remaining steps are setting up your Notion database, creating a Notion connection (integration), and configuring a webhook to automatically trigger a redeployment whenever you update a blog post. Since these steps are relatively straightforward, I won't go into detail here.
However, if you want to dive deeper or run into any issues along the way, feel free to reach out to me via email. You can find my contact details right on the home page 😉