Site History

2019.03.04. 19h • Márton Braun

I’ve owned the zsmb.co domain since the July of 2015, and there has been a website available on it in some shape or form - with some interruptions - ever since. Here’s the story of how I got started, and the evolution it went through to arrive where it’s at today.


C++ for life

Learning C++ in my second semester of university after C was amazing. We had higher level abstractions, classes, and most importantly… A standard library so that I didn’t have to write everything myself. Collections, regexes! It was dreamy. I got so drunk on this power that I wrote the code that powered my initial website. More than a 1000 lines of twisty C++, available here for your reading pleasure.

The blog page of the intitial site

I invented my own simplified Markdown-like syntax for my content, parsed it completely manually with string operations, and rendered perfectly-indented HTML files from it. I also wrote essentially all my CSS by hand at this point.

The projects page of the initial site

Around this time, the projects I wanted to share were also mostly made in C++ and had graphics powered by SDL2. I tended to upload runnable binaries compiled for Windows, plus the source code. Nearly all of this code looks horrible to me now, as it should, but I was sure proud of each project that I got done at the time.

As for the site itself, it had amazing performance thanks to being completely pre-rendered static HTML. I simply served it with an Apache webserver running on my Raspberry Pi. The “Markdown” sources lived in my Dropbox, and I had a shell script on the Pi to trigger a Dropbox download of that sources folder using Dropbox Uploader, run the generator program, and copy things around as necessary.

I’ve decided to make an archived version of this old site available, hopefully generated from the latest version of my sources folder for it. I did have to update a couple things to make links work, as it used to rely on a bunch of hacky .htaccess rules to achieve clean URLs (some still might be broken, if you find one, feel free to tweet at me). You can check it out in action here.

Java rewrite

The next semester brought along Java, where things were so much more carefree compared to C++. I decided it was time for a rewrite and moved the entire generation application to Java, with multiple source files and packages.

You can find this version’s source code here on GitHub, while still very custom and only capable of generating this specific site, it’s much better than the C++ implementation. I actually used this code to generate the archive linked above, since it was easier to compile and run.

The current looks

This original version of the site was eventually shut down sometime late 2016 for reasons I can’t remember anymore (the last post was in August, as evidenced by the archive and Twitter). Perhaps it was the lack of relevancy to my then current interests as a developer, which turned very much towards Kotlin and Android by then. Perhaps it was some server configuration issue I couldn’t be bothered to fix. Either way, that was the end of the initial design and content.

v1 - powered by Kagu

In the fall of 2017, I’ve built a very basic framework for writing single-page web apps using KotlinJS, named Kagu. (If you decide to check it out, be warned: the docs are in whatever state they’re in, and I can’t currently provide support for this project.) This was a very exciting dive into all aspects of KotlinJS.

I had some example projects for the framework, but in the spring of 2018, I’ve started building a new site for this domain, on Kagu. Making it capable enough to host a blog was always in the back of my mind, and this turned out to be an excellent test project to find bugs and improvement opportunities in the framework.

Architecture of the Kagu version

The overall architecture ended up being a bit of a mess. I had a 3-module Gradle project, with a common module containing my DTOs, with the backend (JVM) and frontend (JS) modules depending on it.

The backend was a Spring Boot application serving as my backend, accessible through a REST API and storing articles in a MongoDB. These articles were essentially JSON objects, containing the articles in one of their fields in ugly, ugly escaped Markdown. At least it was actual Markdown this time.

I’ve learned a lot about about Spring Security while implementing the backend, which I’ve hopefully done so correctly and fairly securely. I also used Spring WebFlux, and the routing DSL - I mean, just look at how beautiful this is:

"/public".nest {
    "/articlesummaries".nest {
        GET("/", publicArticleHandler::getAllArticleSummaries)
    "/articledetails".nest {
        GET("/id/{articleId}", publicArticleHandler::getArticleDetailById)
        GET("/url/{url}", publicArticleHandler::getArticleDetailByUrl)
    "/custompages".nest {
        GET("/{name}", publicCustomPageHandler::getPageByName)

The frontend was served by an nginx instance, and as mentioned already, was a Kagu application. It had just a couple components, and whenever it needed to load an article, it would ask the backend for the content dynamically. The backend took the Markdown from the DB, rendered it, and sent back the rendered HTML to the Kagu app, which then parsed it into DOM elements using JQuery. And it worked, for the most part.

This version of the site was at first deployed on my poor old Raspberry Pi as well. It handled the 3 Docker containers necessary for running it like a charm, surprisingly. In the April of 2018, I’ve ended up signing up for Linode’s most basic, $5 a month VPS offering, and moved my site there. This cheap server fared significantly better than the Pi, which I ended up having to take out of service soon after anyway.

v2 - powered by Thymeleaf

Whenever an article I wrote would get any sort of little traction, reports of issues with viewing my site kept coming in. In August, 2018 I’ve finally caved and decided to simplify my site for a better user experience. My goal was to get rid of the dynamic content loading voodoo and for readers to receive plain, “static” HTML pages as a response to their requests, with no dynamic behavior on the client site whatsoever.

I’ve opted for using Spring Boot with Thymeleaf templates, since I was sort of familiar with them already. Adding another Spring container was of course no problem, and it could very easily access the contents of my MongoDB instance - I simply copied the model classes and repository interfaces from the backend module.

Architecture of this second revision

The upgrade did wonders for site performance. While not the same as having pre-rendered HTML pages to serve, it was a lot faster than making AJAX requests for rendered Markdown, parsing it into elements, and inserting it into the DOM.

This was a purely frontend experience upgrade, which on one hand was great. It meant way less work than if I had to make changes to the backend as well, which was a rather complex application. Of course, on the other hand, this change did nothing for the clumsy maintenance side of the site, where I stuck to using Postman in a very manual fashion.

v3 - powered by Hugo & Netlify

I’ve heard about Netlify several times from multiple sources lately, most notably from Simon Wirtz praising the service on Twitter. Promises of pushing to a repo and having a site automatically redeployed doesn’t exactly seem magical with the world of CI tools as I know them today - but it was a dream compared to my existing setup.

So, on the 16th of February, 2019, I’ve decided that it was finally time for this change. I remember it like it was yesterday - because it was yesterday. I took a dive into the static site generator world, looked at the popular options, and decided to give Hugo a try.

The setup process wasn’t flawless, but it was smooth. I’ve quickly figured out that VSCode was the way to go for editing a Hugo site, at least for me - it was the editor I knew the most that had a plugin supporting Hugo templates. The official documentation covers almost everything you need to know about how to build your site, and for the things that it doesn’t, the forum has provided me with answers most of the time. Next to the getting started guide, this YouTube video provided me with a good foothold into the way Hugo works, and I referred back to it multiple times.

Converting my Thymeleaf templates was fairly easy (almost a one-to-one conversion from one syntax to the other), although for a more complex site, even this would’ve taken a while. I’ve even added new features after the conversion: support for multiple authors on the site, as well as an RSS feed (the latter of which came with Hugo by default!).

“Architecture” with Netlify

The generation speed of Hugo and then the redeployment speed of Netlify really is something to behold. The whole thing is a couple dozen seconds at most. The web UI of Netlify made many things trivially easy: setting up a custom domain, enabling automatic Let’s Encrypt support and asset optimization, and performing code snippet injections into the site.


Tinkering is fun! Even when it’s about making things work in a completely ill-suited language and environment, with completely the wrong tools. It’s all a learning experience, and it’s great to see that you can push any Turing-complete language to perform whatever work you want for you.

However, some things just need to be quick, stable and reliable, and the best way to ensure that is to make them as simple as possible. In the case of a blog, that means getting rid of as much of the fancy dynamic behaviour as possible, and just serving real, static, complete, self-containing HTML files from a server. For now.


Here’s all the links from the article in one neat list:

You might also like...

Wrap-up 2021

Another year over, a new one's almost begun. Here's a brief summary of what I've done in this one.

Wrap-up 2020

Let's send this one off so that we can get started on a better one. The "usual" recap of what I've done this year.

Getting Only Positive Feedback

A brief discussion of my wonderful imposter syndrome and a call for more criticism (at least towards me).

Wrap-up 2019

Another year has come to an end, so it's time to reflect again. I'll attempt to sum up what I've done this year, how that compares to what I was planning to do at this same time last year, and what I expect to be next.