A quick overview of the stack and structure behind this personal site and blog.
For my personal page I wanted something clean and minimalistic that could be hosted as a static site and with the simplest publishing process possible.
I also wanted to avoid having a database, an admin panel or any sort of CMS. The content is small, the layout is simple and most of the time I just want to write a markdown file, push it and be done with it.
The site is built with Next.js. For something this small it might sound like overkill at first, but it gives me a very nice development experience and static generation out of the box.
The interesting part for the blog is that every post page is generated at build time. The blog index calls getPosts() to read all the files inside the posts/ directory and the individual post page uses getStaticPaths() plus getStaticProps() to generate one route per markdown file.
That means there is no backend serving blog content dynamically. Once the site is built, it is just static files.
For styling I used Tailwind CSS. I like it for small personal projects because it makes it very easy to iterate on spacing and typography without having to spend time naming CSS classes.
Most of the layout is just a handful of utility classes and the blog post body uses the typography plugin so markdown content gets decent defaults for headings, paragraphs and links.
The end result is pretty close to what I wanted: very little custom CSS and a UI that stays simple.
Posts live as plain .md files inside the posts/ folder. Each file starts with a tiny frontmatter block:
---
title: Post title
description: Short description
hidden: false
date: 2021-06-25
---
I wrote a very small parser for this in common/posts.js. It reads the file, splits the header from the body and returns an object containing the metadata and the markdown contents.
This is intentionally simple. I do not need tags, categories, authors, nested metadata or anything fancy, so keeping it small felt better than bringing in extra dependencies.
The markdown body is rendered on the page using react-markdown, which means writing a new post is basically just creating a new file and adding some content.
The publishing flow is also intentionally minimal. Tailwind is compiled into a single stylesheet, Next.js builds the site, and then the project can be exported as static HTML.
So adding a post looks roughly like this:
posts/This setup is probably not the most powerful one, but I think it is a good fit for a personal website. It is easy to understand, easy to modify and does not require me to maintain any infrastructure beyond static hosting.
I really like small websites that do one thing well. In this case that means a homepage, a projects page and a blog with markdown posts.
There are still a couple of things I would like to improve over time, like richer markdown support and better metadata handling, but for now this does exactly what I wanted: it stays out of the way and lets me write.