Having dealt with enough complex solutions in my career, this time around, I decided to build my website in the simplest way possible, using the least amount of code and effort. I wanted something I could code up in a few hours with minimal styling and tooling and keep the dependencies to a bare minimum, as I didn't want to spend time learning and implementing them.
Keep it stupid and simple was the motto!
I have previously tried building this with WordPress, Ghost, and Hugo, but each had issues due to primarily due to reliance on a backend server. Although Hugo offered a static website, it lacked effective collaboration and was build on pure markdown.
What I ended up creating was a minimal HTML & CSS website that uses 11ty as a static site generator, Notion as its CMS and Hetzner Cloudflare to host the site. There is no analytics, cookies, Javascript, fancy new frameworks like NextJS, or additional CMS. All the source code is on GitHub. It can easily be deployed manually through workflow trigger in Github Actions Cloudflare dashboard or using a deployment hook, but that would be overkill for me at this point.
Why use Notion and not basic Markdown? When reviewing, It's easy to collaborate with my family and friends, who might not be familiar with Markdown or GitHub. I use Notion daily anyway, and we are all very familiar with the interface.

I simply created a new database table on Notion named CMS and added a few attributes, as shown above. Then, I made an internal integration on the Notion developer console (yes, it has one) to create the secret key and enable API access for my CMS. Last, the Notion DB must be connected to your internal integration, as shown below.

A script pulls all the content and images from Notion API into markdown files. 11ty takes that markdown as input and generates the static site into a /public
folder with a simple npx eleventy
. The /public
folder is then served with Cloudflare Pages.
$ npm run fetch
$ npx eleventy
$ cd ./public
$ tree
.
├── about
├── images
├── index.html
├── posts
└── style
The only caveat I faced with this setup was that the remote images fetched through the Notion API needed to be appropriately handled and downloaded locally. The n2m.pageToMarkdown
function I used would just insert an embed
instead of the image into the Markdown file. But I’d already solved these issues earlier at Blue Sky and knew how to solve them.

The images could be easily downloaded with 11ty transform like this
eleventyConfig.addTransform("download-images", downloadImages);
The downloadImages
would just fetch the images, store them in the local directory and update the src in the HTML code.
It took me just a couple of hours to pull all this together, and the average build time was less than 20 seconds.
November 2024 update: I made a significant change by migrating away from Cloudflare to a Virtual Private Server (VPS). This change allowed me to serve the site using Caddy, a lightweight web server, while simultaneously automating the build process through GitHub Actions.
Although anecdotal, the builds are faster and more transparent, making debugging easier. Additionally, the site loads slightly faster by 50 ms. However, unless you plan on running other services on the VPS, it’s best to use Cloudflare Pages. It’s an excellent service for hosting a simple static site.