~ /www/0xflo.dev

Tech-Stack

This site is a static Hugo project with no JavaScript and no framework. Here is how it fits together.

This website's architectureA Git repository of content, templates, assets, and data is pushed to Uberspace, where Hugo builds a static site — including an image pipeline that turns page-bundle images into responsive AVIF and WebP derivatives — which Caddy serves to visitors; the same repository is mirrored to GitHub.PUSHBUILDSERVEMIRRORUBERSPACE · HOSTREPOSourcecontent/ layouts/ assets/BUILDHugostatic site buildOUTPUTpublic/HTML · CSS · WebPSERVECaddyzstd · HTTP/2CLIENTVisitorbrowserREMOTEGitHubremote mirrorIMAGE PIPELINESRCPage bundlescontent/ imagesBUILDHugo imagesresize → AVIF · WebPOUTPUTpublic/ imagessrcset · lazyLEGENDfocal stepartifactexternal

Static by default

Every page is generated ahead of time by Hugo and served as plain HTML, CSS, and images. There is no application server and no client-side JavaScript, so there is nothing to fail at runtime and nothing to hydrate.

What lives in the repository

How it ships

The repository is the single source of truth. Pushing the main branch triggers the deploy: Uberspace receives the push, runs Hugo, and publishes the built public/ directory, which its Caddy front end serves over HTTPS with zstd compression. The same push mirrors the repository to GitHub.

The image pipeline

Images are the heaviest thing a site like this ships, so they get their own stage in the build. A raster image lives in its post’s page bundle and is referenced with plain Markdown; the render hook (layouts/_default/_markup/render-image.html) turns it into a responsive <picture> — an AVIF <source> and a WebP <img>, each a srcset of widths up to the image’s natural size, with sizes, intrinsic width/height (so nothing shifts), loading="lazy", and decoding="async". Nothing is upscaled, and an image is not fetched until it scrolls into view. The imageboard reuses the same idea for its thumbnails.

Link previews get the same care in miniature. scripts/make-og-card.py draws the Open Graph card from the IBM Plex Mono glyph outlines and writes assets/og.png; the build then fingerprints it, so the og:image URL changes whenever the card does and messengers refresh their cached preview instead of serving a stale one.

Small, fast, and accessible on purpose


The diagram was generated with the diagram-design skill.