EN FR

Chapter 01Understand

Why this tool exists

The real context, the options ruled out, and the reason behind each refusal. This chapter teaches you nothing to do: it explains why everything else is done the way it is.

7 min read10 sectionsChapter 1 / 22

The starting point

An agency delivers brochure sites to non-technical clients: bakeries, practices, craftspeople, associations, small service businesses. The site is built once, properly, and is meant to live for several years.

Three weeks after delivery, the same thing always happens:

“Hi, could you change the photo on the home page and replace ‘open on Mondays’ with ‘closed on Mondays’?”

That request costs something every time: an email round trip, a fifteen-minute intervention billed as forty-five, a deployment, a check. Multiplied by ten clients over two years, it becomes a permanent operating load for uninteresting work. On the client's side the experience is worse still: they wait two days for one word, and eventually stop asking — the site goes stale.

So the real need is not “a CMS”. It is: let the client change a text, a photo, a testimonial, without us, without training, without breaking anything, and without the site losing what justified building it this way — its speed and its visibility.

What was ruled out, and why

OptionWhat it bringsWhy it was ruled out
WordPress The client edits; everybody knows it. A database and an application server to maintain per site, endless security updates, plugins that break, hosting that is slower and dearer. For a seven-page site that changes four times a year, that is a whole infrastructure to watch over.
Headless CMS (Contentful, Sanity, Strapi…) Structured content, clean API, good tooling. A subscription per site, one more account for the client, and the content moving out to a third party. Above all: the client edits in a dashboard, not on their page — they have to picture the rendering from a form.
Git-based CMS (Decap, Tina…) Content stays in the repository, no database. This came very close. But editing is still a dashboard with a file tree, and authentication assumes the client has a Git account or an identity provider. Two things a baker will not have.
Nothing — the client asks the agency again Zero development. That is the starting situation, and the one we want to leave.

What the first three share: they make editing possible by moving the client away from their page. The dashboard is where a non-technical client gives up. They do not know whether “hero block, intro field” is the paragraph in front of them, and they have no reason to know.

The constraint that decided everything

A brochure site exists to be found. Today it must be found twice: by search engines, and by the assistants that answer on their behalf — GPTBot, ClaudeBot, PerplexityBot, Google-Extended.

The technical fact

Those crawlers render little or no JavaScript. Content injected in the browser is, to them, content that does not exist. And their crawl budget is shorter than Googlebot's: a heavy page is visited less often and less deeply.

This constraint eliminates a whole family of solutions at once: those where content arrives after the HTML. It requires that every visible word of the site be in the served HTML, before a single line of JavaScript. It explains the project's strictest rule — no hydration on an editable zone — and the automated check that enforces it (check-html).

The two ideas

Two decisions came out of that, and everything else follows from them.

Idea 1

Content is a file, injected at build time

Each page has a JSON file. Astro reads it at build time and writes the text into the HTML. At runtime there is no content left to load: there is only a static file on a CDN. No network call, no database, no latency.

Idea 2

Editing happens on the page, nowhere else

The client opens their site, enters a key, and an interface overlays their own pages. They click the text they want to change — the one they can see — and change it. Nothing has to be mentally translated between a form field and a rendering.

A consequence of idea 1 is that publishing is not a database write: it is a commit, which triggers a rebuild of the site. Published content is frozen into the HTML thirty to sixty seconds later. That delay is the price of the guarantee; it is announced to the client in the interface, in plain language.

Git as the database

Since content is a file, its storage is the repository. Without writing a line, you get:

  • history — who changed what, when, with the exact text before and after;
  • restore — going back is a standard gesture, not a feature to build;
  • backup — the repository is already replicated; there is no database to back up;
  • review — a content change reads as a diff.

It is also what makes the host interchangeable: the content belongs to no platform. The day hosting changes, you redeploy the same repository elsewhere.

One author, one key

The client has no GitHub account and will not have one. The repository and the write token belong to the agency. So the question becomes: how do you let a person write into a repository they do not know exists?

The answer chosen is the smallest one that holds: one key per site, randomly generated, of which only the argon2id hash lives on the server. The client receives it once, stores it in their password manager, and types it on /admin. No account to create, no software to install, no third-party identity provider in the loop.

The accepted trade-off

One key per site means one author per site: history does not distinguish two people sharing the key. That is a choice, not an oversight. A need for individual traceability is handled by replacing a single implementation — auth.ts — with delegated authentication. See Security and authentication.

What the tool refuses to do

The scope is frozen, and the list of refusals matters as much as the list of features. Not implemented, and not to be implemented without an explicit decision:

  • multi-role approval workflow;
  • granular per-field or per-page permissions;
  • visual content versioning (comparing two versions on screen);
  • A/B testing;
  • forms with stored submissions;
  • site search, comments, member area;
  • layout editor — moving or creating blocks.
The signal

If one of these needs comes up and it is real, it is not a feature to add: it is a sign that this particular project needs an off-the-shelf CMS. Saying so during scoping costs a conversation; discovering it in the third month costs the project.

The boundary, announced at delivery

An editing tool without an explicit boundary drifts endlessly: after text comes colour, after colour the position of the block, after position the whole page. So the boundary is set on delivery day, in one sentence:

The client's

Texts, images, videos, list items. What is being said.

The developer's

Structure, layout, theme, navigation. How it is shown.

That boundary is not just talk: it is enforced by the code. The client does not pick a colour, they pick one of the five colours of their theme; they do not pick a size in pixels, they pick one of seven steps. A value outside the list fails the build. See Theme and styles.

Who it is for

Good ground

  • Brochure sites of 3 to 30 pages, one to three languages.
  • A single point of contact on the client side.
  • Content that changes a few times a month, not several times a day.
  • An agency running several sites that wants one codebase to fix.

Bad ground

  • A daily blog, a catalogue of thousands of references.
  • Several simultaneous writers with mandatory review.
  • Content that depends on a logged-in user or on live stock.
  • A need to create whole pages without a developer.

What it costs

Version 1 was built in eight batches, for roughly twenty days of development. That figure only matters next to the following one: each additional site costs one to two days, front-end integration included, because none of the editing logic is rewritten — it is consumed as a versioned dependency.

That is the only reason the project is split in two (inline-core shared, the rest specific to the site), and the only architectural rule that really matters over time: a security fix must reach ten sites by changing one version number, not through ten edits to hunt down.

Next, how it all fits together: How it works.