A content backend you can rip out without breaking the site
Headless CMS lock-in is a slow tax you pay forever. We built a seam: file-backed today, headless tomorrow, and a file fallback the day the database is down.
Picking a CMS used to mean marrying it. Your templates learn its quirks, your content model bends to its schema, and three years later 'just switch' means a rebuild. We designed the content layer so that decision stays reversible.
Everything that reads content goes through a single provider-agnostic adapter, switched by one environment variable: `CMS_PROVIDER` is either `file` or `headless`. In file mode, content lives in versioned source — diffable, reviewable, deployed with the code. In headless mode, the same adapter talks to a remote source and caches a published snapshot. The pages above it don't know or care which is active; they call the same interface and get the same shape back.
The part we're proudest of is the failure behavior. The adapter reports its own source on every read — `live-remote`, `snapshot-cache`, or `file-fallback` — and when the remote source is unreachable, it falls back rather than blanking the page. The database going down becomes a degraded read, not an outage. Visitors see content; we see a logged fallback reason. That's the difference between an incident and a non-event.
What we refuse to do: hardcode a vendor's API calls into page components, let content modeling get dictated by a CMS's admin UI, or build a site that returns errors the moment its backend hiccups. We also don't pretend the seam is free — an abstraction has a cost in indirection. We pay it knowingly, because the alternative is paying a migration tax later, with interest.
The principle: depend on a seam, not a vendor. If your content layer can be swapped with an environment variable and survives its own backend going dark, you own your content. If swapping it means a rewrite, the vendor owns you. We'd rather absorb a little indirection now than hand someone else a veto over our roadmap.