how i set up this blog

setting up a blog with plain html and no build tools

What's this, a barebones html+css blog? It's not using React, not even using any[1] javascript? And it's not hosted on Vercel or Netlify?

That's right, I'm not even using any build tools. Everything is just plain .html files and everything in the <head> tag and that header you see on top is copy-pasted. Screw code deduplication and consistency, one day I'm going to forget to copy paste that header and I don't care.

The server

I'm using good old nginx to serve the webpage from a single server on Hetzner. For SSL, I'm using Let's Encrypt to get a free SSL certificate, and Certbot to renew it automatically. I'm also using Cloudflare to manage my DNS records and get some free CDN.

The file directory structure is also as simple as you can get:

|- blog/
|  |- 2020-01-10 first blog owo.html
|  \- 2020-01-10 how i set up this blog.html
|- img/
|  \- pfp.jpg
|- misc/
|  |- draft.html
|  \- nginx-autoindex-before.txt
|- static/
|  |- github-dark.min.css
|  |- highlight.min.js
|  |- template.js
|  \- pico.css
\- index.html

It's so simple it's borderline boring. The only (slightly) interesting thing is the nginx config:

server {
  listen 80;
  listen [::]:80;
  server_name _;

  return 307 https://$host$request_uri;

server {
  listen 443 ssl http2;
  listen [::]:443 ssl http2;

  # boring ssl stuff here

  root /var/www/;

  location / {
    if ($request_uri ~ ^/(.*)\.html) {
      return 302 /$1;

    try_files $uri $uri.html $uri/ =404;

    location = /blog/ {
      autoindex on;
      add_before_body /misc/nginx-autoindex-before.txt;

    location ~\.(draft.html|draft)$ {
      deny all;
      error_page 403 /misc/draft.html;

It's the usual config, with SSL redirects and stuff, but I've also added a few fun stuff to it:

How I manage posts

There's a million ways I can manage posts and other files on my server. Using some CI/CD pipeline, mounting the server on my machine, pushing files around using rsync/rclone, etc. In the end, I just went with Syncthing.

Using Syncthing, I can set up a folder on my machine, and then sync it with the webserver root folder. I can then edit files on my machine, and all of the changes will be automatically pushed to the webserver.

I chose this method because it's easy to set up and, unlike git, would easily work with large binary files without any additional setup. I can just drop stuff in the folder and it'll eventually end up on the server. And plus, having two copies of my stuff is great for redundancy.

I do have a git repo set up for the whole site, but I'm just using it for version control for the posts and other text files and does not include any images or other binary files.

Comments and syntax highlighting

You may have noticed the fancy colors on the nginx config above. That's because I'm using highlight.js to do the highlighting on the client side. There's also a comments section below, and I'm using Cusdis for it.

Since neither of those are essential for the website to work, I decided to load them with a little script that injects them after the page is loaded. You can read the script at /static/template.js.

That's all

The post is over and I don't feel like writing the ending.

[1] I'm using highlight.js to perform syntax highlighting for code blocks, and cusdis for comments, but they're completely optional and the blog is still usable without them.