Five sites, about a thousand pages, no CMS, no database, no build server beyond a script that runs on my laptop.
That sounds like a boast. It is mostly a description of a constraint I chose and then had to live with.
The five, by size
The pages are not one site with five sections. They are five separate sites with different shapes:
- a reference with 416 pages in four languages (repair guides, animated diagrams)
- a drumming reference with 308 pages in two languages
- a pronunciation reference with 166 pages across two interface languages and three phoneme inventories
- a utility site with 68 pages, most of them single-tool pages
- a mortgage calculator site with 43 pages, one country, one decision
Roughly 1,000 HTML documents, all generated. Nothing renders on request except the static file itself.
What is actually shared
Almost nothing at the content layer, and that is the point: each site's data model is different, because the subject is different. A repair guide is a decision tree; a phoneme page is a measurement table; a rudiment is a string of sticking.
What is shared is the shape of the pipeline:
- source data (JSON, strings, measured values)
- a render step that produces every page
- a sitemap written from the same list the renderer used
- a check that the sitemap and the rendered files agree
That last step exists because of the first real problem I hit.
Problem one: the sitemap lies quietly
A sitemap that disagrees with the rendered files is worse than no sitemap, because it looks authoritative. The failure is silent: pages get added, the sitemap is generated from a slightly different list, and three weeks later a crawler is being pointed at URLs that 404.
The fix is boring and it is the only thing that works: generate both from one list, and then diff the output against the filesystem on every build. If they disagree, the build fails. Not warns — fails. A warning gets ignored for a month.
Problem two: two axes multiply faster than you expect
One of the sites has two independent language choices — the interface language and the language being described. That is not 2 + 3 pages, it is 2 × 3 sets of pages, and the URL has to carry both in a fixed order so that switching one axis keeps the reader on the same content.
The trap is that it works on the homepage and breaks four levels deep. Every axis has to be switchable from every page, which means every page needs both controls, which means the navigation surface doubles and there is no clever way around it.
Problem three: the same article twice
With five sites and two publishing channels, it is easy to write the same argument twice with different examples and publish both. Search engines are not the main risk; the risk is that I stop noticing, and the sites start repeating each other in a way a reader can feel.
The rule I use now: one angle per site, and if two sites genuinely share an argument, write it once on the site that owns it and link across only where a reader would actually want the other page. That second condition is doing all the work — most of the time it is false, and the answer is to cut instead of link.
What static does not solve
Static does not mean cheap to change. A template edit means rebuilding every page, and with five sites that is five rebuilds and five chances to introduce a typo that appears in a thousand documents.
It also means no search index, no per-user state, and no easy way to run an A/B test. For reference sites where the value is the numbers being identical everywhere they appear, that is a fair trade. For anything that needs accounts, it is the wrong trade, and I have passed on several ideas for exactly that reason.
Why not a CMS
I tried the alternative once: a database, a template engine, an admin panel. What I got was a site where the content existed in two places — the files I edited and the rows I forgot to update — and no way to tell which was true.
The version that works for me is unglamorous: everything is a file, everything is regenerated, and if the build passes, the site is consistent.
Three of the five, if you want to see how differently the same pipeline can be shaped: a utility site where each page does one job, a pronunciation reference built on measured audio, and animated repair guides where the diagram is the explanation.
Top comments (0)