How this site is built
A note on how this site is put together. Not a case study — it is a small marketing site, and treating it as a showcase would be silly. But people ask what the machinery is, and some of it is unusual enough to be worth writing down.
What it is
Eleventy 3.1.6, Nunjucks templates, and CSS written by hand. There is no framework, no component library and no CSS pipeline: one stylesheet, about 14 KB over the wire once compressed. The build produces 36 pages of static HTML, which S3 serves and CloudFront caches.
0 runtime dependencies. Nothing this site sends you pulls in anyone else's code. There are 6 development dependencies, which is Eleventy and the things that build and check the output; none of them reaches a browser.
Two scripts ship. enhance.js is about 6 KB compressed and runs on every page — copy buttons, the social-card tool, the / palette, progressive niceties that the page works without. The second is about 80 KB and loads on exactly two pages, because it is a game, and it would be rude to send it to everyone else.
The palette is deliberately absent from those two pages. Both are a shell or a game that reads raw keystrokes, and a sitewide handler taking / away from them is a bug this site has already had once, from a skip link.
What it will not do
The content security policy has no 'unsafe-inline', which means no inline style="" attributes and no inline <script> anywhere in the markup. Everything is a stylesheet class or a hashed file. This is a mild inconvenience roughly once a month and it removes an entire category of problem permanently, which seems a fair trade.
There is no analytics beyond a cookieless page-view counter, no tag manager, no third-party fonts fetched at runtime, and nothing that follows you anywhere.
Rather more tests than this needs
There are several hundred tests across 35 files, for a site with 36 pages. That is disproportionate and we know it. What made it worth doing is that the site deploys itself every hour without anyone looking at it, so anything that can go wrong quietly will eventually go wrong quietly.
The ones worth describing are the ones that check the checks:
guardsBreaks the site on purpose, one violation at a time — a dead link, a wrong company number, a heading outline that starts at h5 — and fails if the test suite stays green. A suite that asserts the build is clean says nothing about whether it would notice if it weren't.mutantsThe same idea aimed at logic rather than content: flip a comparison, shift a threshold, invert a return, and check something fails.ci-checkRuns the suite the way CI runs it — a clone at the pipeline's own depth — because a test that reads git history passes locally and fails on a shallow checkout, and reports which tests skip there, since a test that skips in CI is not a test CI ran.og-corpusandog-fuzzThe social-card checker against 75 real websites and 250,000 generated tag-soup cases, because the interesting failures come from markup nobody would write deliberately.
The recurring lesson, and the reason those exist: the thing doing the checking is wrong more often than the thing being checked. A test that cannot fail is worse than no test, because it also stops anyone looking.
How it ships
Every push runs the build, the full suite, and terraform fmt and validate over the infrastructure. The site then redeploys itself hourly whether or not anything changed, which is how version numbers and release dates on the product pages stay current: they are fetched at build time rather than typed in, so the page is only ever as stale as the last hour.
Uploads are ordered so there is never a broken intermediate state — hashed assets first and never deleted, HTML last, so no page can reference a stylesheet that has not landed yet. Afterwards a smoke test hits the live site and checks the pages, the security headers and the redirects.
Deploys that a human starts get one extra step: a read of the actual prose on every changed page before anything goes out. Machines are good at catching a dead link and hopeless at catching a sentence that is true but unwise.
The infrastructure
S3 and CloudFront, with Route 53 for DNS and Lambda behind the one API this site offers. All of it is Terraform, in the same repository as the site, and npm run drift plans every configuration read-only to check that what is deployed still matches what is written down.
The bird
The 404 page is not a 404 page. Neither is this one. Both were built for fun on evenings, they are the reason one of those script bundles is 80 KB, and no apology is offered for either.
If any of the above is useful to you, or you want the same discipline pointed at something larger, get in touch.
Have a big idea to build, a problem to solve, or a system that’s overdue an upgrade?
Get in touch