I opened my personal site's project after two years without touching it. The first thing I saw was not the code: it was the server's process list. Two applications running, a MySQL database, a subdomain for the admin panel, and a main domain that, depending on how you arrived, answered with a 500 error.
All of it to serve five pages that had not changed since 2023.
What was there
The previous version was a Next.js 13 front end consuming a Strapi API. The CMS lived at strapi.jopsa.me with its own database, and the front end ran in a separate process. On paper, the right architecture: a panel to edit content without touching code.
In practice, I logged into that panel about three times in two years.
I found the 500 by accident, opening the site from a tool that does not send the Accept-Language header. The middleware assumed it was always there, and without it the request blew up. It had been like that for months, failing for any bot or client that skipped the header. Nobody told me, of course: nobody reports the errors on a personal site.
The question
Before rewriting anything I asked myself one thing: what is the CMS giving me that a text file would not?
The honest answer was nothing. There is no newsroom, no approval workflow, no twenty editors. There is one person writing, and that person knows how to use git. What the CMS was giving me was a database to back up, one more process to watch, a version to upgrade and an extra attack surface.
What I did
I rewrote the site with the content in files: YAML for pages and Markdown for articles, one per language. Every file is validated against a schema at startup, so a mistyped field breaks the build on my machine instead of in production.
Pages are composed of blocks. Each block is a type declared in the schema and a component in the code; content never invokes an arbitrary component. Adding a new section is two things: describing its shape and drawing it.
The result is 22 routes generated at build time. No database, no CMS, no queries while someone waits for a page.
The two stumbles that cost me an afternoon
The server could not compile. The VPS runs Rocky Linux 8, with a glibc from 2018, and Next 16's compiler wants a newer one. Rather than fight the system, I moved the build to GitHub Actions: it compiles a self-contained bundle there, rsyncs it and restarts the process. Every push to the main branch deploys on its own, after passing lint, types, tests and content validation.
A redirect loop that did not exist locally. In production the home page bounced forever between / and /es. The cause was an environment variable: with HOSTNAME=127.0.0.1 set, Next compared the origin of its internal rewrite against the boot origin, they did not match, it treated the rewrite as external and sent it back through the proxy. Removing that line fixed it. I left the reason in a comment so I do not fall for it twice.
What is left
One process instead of two. No database. A deployment that takes two minutes and starts with git push. And, as a side effect of retiring the old stack, seven gigabytes back on the server.
The lesson is not that content management systems are bad. It is that I was paying maintenance for flexibility I never used. When I write, I open the editor and commit; the site publishes itself. For what I need, that is faster than any panel.



