This is my personal blog. It is a lightweight and efficient static site built with Go, templ, and UnoCSS.
One important requirement was that all my blog posts were to be written in markdown (in /content). It then turned out to be
a bigger challenge to get the markdown file generation working than actually creating the blog. I first started out using pandoc
to generate the markdown externally, but pandoc does some very weird styling and the syntax highlighting colors they support look
really bad. I instead then opted for goldmark which is also in use by the hugo.
To get the blog running locally you first need a bunch of tools. The easiest way to get up and running is with mise
where you can install and activate the required tools with mise activate. If you want to manually install the tools
look into the mise.toml file for the exact versions required.
Justfile makes it easier to just run the required programs. Look into the justfile file to see the full commands.
-
Install the frontend dependencies:
npm install
-
Run templ to generate the go files that are then required:
templ generate
-
Run the webserver:
just d
-
In a separate terminal, run UnoCSS to continuously update the CSS file:
just css-watch
Blog post images are converted to WebP at build time. To do the same locally (requires cwebp/gif2webp from libwebp or ImageMagick):
just webpIt's also possible to start up the website using Docker:
docker compose up --buildThe image is built in multiple Alpine stages: Go builds the server, Node runs UnoCSS, and libwebp converts post images. The container serves brotli when the client accepts it, falls back to gzip, and otherwise sends uncompressed responses.
For extensive testing, Playwright is used. To make the install simpler, there's a Dockerfile
in e2e/Dockerfile.playwright. Build and run it from the root directory.
docker build -t htmx-playwright -f e2e/Dockerfile.playwright .
docker run --rm -it --network host htmx-playwright /bin/bashPosts can be created with the just new recipe. Simply execute the following:
just new content/posts/name_of_post