Stack
How this site is built
We audit other people's applications, so it would be odd if ours did not hold up. Here is what it is made of, and for each claim a way to check it. None of it is meant to be taken on trust.
Lighthouse
- Performance
- 100
- Accessibility
- 100
- Best Practices
- 100
- SEO
- 100
- Agentic Browsing
- 3/3
Home page bhpslabs.com/cs, measured with Lighthouse in Chrome on .
In numbers
- 'unsafe-inline' in the CSP
- 0
- unit tests
- 460+
- Playwright end-to-end tests
- 230+
- home page JS (brotli)
- ~180 kB
- CSS (gzip)
- 8 kB
- languages, every page in both
- 2
Foundation
The site is a single TypeScript application. The server and the browser share the same types, so a changed address or data shape shows up as an error in the editor, not in production.
TanStack StartandTanStack Router: server rendering, typed routes and parameters. Why we picked it over Next.js is on the blog.React 19,Vite 8andNitroas the server. It runs onNode 24in Docker as an unprivileged user.Tailwind CSS 4with our own tokens for day and night mode. Components never branch on the mode; tokens do.Paraglidefor translations: messages compile to typed functions, so a mistyped key is an error in the editor, not a blank on the page.TypeScript 7,OxlintandOxfmt. Type checks, lint and formatting run as one command,pnpm run cq, and are part of CI.
Performance
Every public page is prerendered at build time. One list of addresses feeds both the prerender and the sitemap, so they cannot drift apart.
- JS and CSS are precompressed to gzip and brotli and carry a content hash in their name, so browsers cache them for a year (
immutable). - HTML is always revalidated (
must-revalidate): a new article is visible right after a deploy. - Two variable fonts instead of a set of weights, both preloaded so text does not jump once they arrive.
- The raster in the hero is drawn to a 2D canvas and has its own end-to-end frame-budget test. It runs alone, so it measures rendering, not the load from other tests.
Security
The Content Security Policy is built for each HTML response separately. script-src lists the SHA-256 hashes of exactly the inline scripts in that response. A nonce would not work: the pages are prerendered and the nonce would freeze into the file.
Strict-Transport-Securitywithpreload,Cross-Origin-Opener-Policy,X-Content-Type-Options,X-Frame-Options: DENYandReferrer-Policy.Permissions-Policyswitches off 14 browser APIs the site does not need: camera, microphone, location, payments, USB and more.- Only video from
youtube-nocookie.comand Vimeo can be embedded. Nothing else gets into the page. - Traffic is measured by Umami on our own domain, without cookies and without a consent banner.
- CI can generate a CycloneDX SBOM and check it against the requirements of the EU Cyber Resilience Act (CRA).
For search engines and AI assistants
The site has readers that are not people. Search engines and language models get the same content as a visitor, in a shape that suits them.
- Every page has a canonical URL,
hreflangfor both languages and one JSON-LD graph: company, site, page, breadcrumbs and, for articles, the author. - The sitemap gives a change date only where we actually know it. The build date would be a false freshness signal.
- The same address returns markdown instead of HTML when a client asks with
Accept: text/markdown, so an agent reads the content without navigation or scripts. /llms.txtsums up the company for models./.well-known/agent-skills/index.jsonand/.well-known/ai-catalog.jsondescribe what an agent can do on the site; aLinkheader on every page points to them.- Through WebMCP the site offers tools to in-browser agents: open a page, get contact details and send an enquiry. The tool description tells the agent to send it only for a person who asked for it and confirmed its content.
robots.txtallows AI crawlers and uses aContent-Signalrule to say what the content may be used for.
Blog
Articles are markdown in the repository, next to the code. At build time unified (remark and rehype) processes them and Shiki highlights the code, so no highlighter runs in the browser.
- An image without alternative text stops the build. Inaccessible content cannot ship by accident.
- A YouTube or Vimeo link on its own line turns into a cookie-free embedded video.
- Each language has an RSS feed with the full text of the articles, and each author has their own.
Accessibility
Accessibility is tested like everything else: automatically.
- Playwright runs
axeover the pages in both colour modes and both languages. - Colours carry a contrast obligation. Orange as text has its own darkened token, because the original fails on the light background.
- A skip link, page-change announcements for screen readers, a visible focus ring and respect for
prefers-reduced-motion.
Tests
Unit tests in Vitest and Testing Library guard the logic: the CSP, language negotiation, markdown for agents, the feed, the forms. End-to-end tests in Playwright walk the site like a person: navigation, keyboard, colour modes, SEO tags and accessibility.
For the curious
The >_ mark in the top bar opens a terminal. It knows ls, cd, cat, whoami and a few more commands that let you read another page without leaving the one you are on. There is a snake in it, and rm -rf does something too.
Check it yourself
You do not have to take any of this on trust. A terminal is enough:
npx lighthouse https://bhpslabs.com/cs --view
curl -s -D - -o /dev/null https://bhpslabs.com/cs | grep -i content-security-policy
curl -s -H "Accept: text/markdown" https://bhpslabs.com/cs/audit
curl -s https://bhpslabs.com/llms.txt
curl -s https://bhpslabs.com/.well-known/agent-skills/index.json
curl -s https://bhpslabs.com/cs/blog/feed.xml