BUBC
A club website rebuilt to outlive the committee that commissioned it. Editors publish a race report in five minutes, it targets 95+ on Lighthouse, and it runs for about ten pounds a year.
What it had to do
Recruit rowers, keep alumni interested, and give sponsors something credible to look at. But the real constraint was organisational, not technical: a university club's committee turns over every year. Any site that needs a developer to update it dies quietly about fourteen months after launch.
So the brief I set was that a non-developer should be able to publish a race report in under five minutes, and the running cost should be small enough that nobody is ever tempted to cancel it.
What I chose
Astro with static output, content in Sanity, hosted on Vercel. One repository, two applications, no server to maintain.
The alternative I rejected was a conventional CMS like WordPress. It would have been faster to stand up and would have handed the next committee a database, a hosting bill, and a security surface. Static output means the worst thing that can happen to the site is that it stops being updated — it cannot go down or get compromised in the usual ways.
Editors work in Sanity Studio. Publishing fires a webhook at a Vercel deploy hook, and the whole site rebuilds in around a minute.
How it works
Astro pulls every page from Sanity's GROQ API at build time and writes static HTML and CSS. Vercel serves it from the edge and rebuilds on push or on publish. Forms go to Formspree, the newsletter to Buttondown — both env-gated, so neither is a hard dependency.
What it cost
Roughly ten pounds a year, which is the domain. Everything else sits inside free tiers, deliberately.
The trade-off is that content changes require a rebuild rather than appearing instantly, and that genuinely dynamic features — a members' area, live race scoring, a shop — are off the table. For this club that was the right exchange; we link out for those instead.
What I'd change
I would write the editor documentation before building the schema rather than after. Designing the content model around what I could build, then explaining it to editors, produced a couple of fields that make sense to a developer and to nobody else.