npm audit had one critical finding here (the Astro 5 advisories, among them the AVIF RCE) — irrelevant at runtime for a static site served by nginx, but the build toolchain ran it. Now 0. Build image node 20 -> 22, and npm ci only: the old '|| npm install' fallback meant a broken lockfile would silently build something untested. Checked in a real browser: all six pages 200, sheet drawn, PDF download measures 210.00 x 297.00 mm in both languages, no horizontal scroll at 390 px.
klarbild-demo
The product and demo page for Klarbild, live at klarbild-demo.heidrich-digital.de.
Two static Astro pages — / in English and /de/ in German, from one shared
component and one copy file (src/lib/copy.ts). The languages are separate URLs
rather than a runtime switch, so each one is linkable, indexable and works without
JavaScript; the button in the header is an ordinary link. The interesting part is src/lib/playground.ts: it
imports src/engine/printlayout.ts and src/engine/paper.ts verbatim from the
Klarbild repository and runs them in the visitor's browser. So the sheet you see
being laid out is not a mock-up — it is the application's own arithmetic, and the
PDF the page hands you is drawn from the same placements (with pdf-lib in the
browser rather than sharp on a server, which is why it carries outlines instead of
photographs).
The preset builder in the image-generation section does the same with
src/engine/format.ts: it composes a real Klarbild recipe and shows the exact
target pixels, but it never calls a model. Generating on a public page would mean
a key on that page and a bill for every curious visitor — and the picture would
say something about the model rather than about Klarbild.
Nothing is uploaded and there is no backend.
npm install
npm run dev
Keeping the engine in sync
src/engine/* are copies. When the print engine changes upstream, copy them again:
cp ../klarbild/src/lib/{printlayout,paper,printoversize,format}.ts src/engine/
cp ../klarbild/src/styles/tokens.css src/styles/tokens.css
# printoversize.ts imports './printlayout.ts'; drop the extension for the bundler
sed -i "s#from './printlayout.ts'#from './printlayout'#" src/engine/printoversize.ts
Deployment
Dockerfile: Node builds the site, nginx serves it on port 80. Coolify deploys on
push to main.