How this site is built
How this site's pages, assistant, headers, tests and server are put together, taken only from what is in its repository.
Pages that read without JavaScript
It is a React 18 app built with Vite. After each build, a prerender step writes one HTML file per page from the same content the pages render, plus llms.txt and llms-full.txt for AI crawlers. Search engines and people with scripts off get a readable version of every page.
An assistant with no LLM
ShaafAI, the chat in the corner, answers from a hand-written knowledge base inside the browser. It uses TF-IDF retrieval with fuzzy matching. There is no API key, and no question is sent to a model.
Security headers on every response
Every response carries a Content-Security-Policy, HSTS, a strict referrer policy and a permissions policy that turns off camera, microphone and location. A test fails if the server's headers drift from the alternative host configuration.
Tests, and a gate before anything goes live
Unit and component tests run in Vitest, and Playwright drives the built site with axe accessibility scans. Pushing the live branch deploys it, so a pre-push hook runs lint, the tests, the build and a simulation of the production host first.
One Node process serves the pages and the API
A single Node process serves the built pages and an API for the contact form and guestbook. When they are configured, data is kept in SQLite and contact emails go out through Resend, behind a honeypot and rate limits. Without them, the form falls back to a plain email link.