Architecture
How SnabbSajt fits together - the load-bearing pillars and where to find things.
SnabbSajt is an opinionated, bilingual (sv/en) website builder for small businesses, built on Next.js (App Router), React, TypeScript, Tailwind, Clerk and Convex, deployed on Vercel.
The six pillars
- Two-world model - draft edits live in normalized, mutable tables; publishing
writes an immutable snapshot (
siteVersions). The public site reads only snapshots, so editing can never corrupt a live site. - One shared renderer -
components/site-sections/SectionRenderer.tsxrenders the editor canvas,/preview, share links (/p/<token>) and the public/site. Preview equals production; never fork it. - Structured content - section
contentis a discriminatedv.unionkeyed bytype, validated on every write. No raw HTML, no raw hex. - Constrained theme - themes are pre-validated, AA-safe tokens (palette, font, density, radius, button) mapped to CSS variables.
- SEO as system output - metadata, JSON-LD, sitemap, robots, hreflang and canonical are derived from business data at publish time and frozen in the snapshot.
- Plain language, bilingual - every admin string goes through
lib/i18n.ts(sv/en/pl).
See the rest of this section for Routes, Data model, Auth and permissions, Publishing and the AI system.
Building a site for a client
If you are here to build in your own code and hand the result to a customer, these five pages are the whole path, in order:
- Build with Site Kit - author against the typed section registry, validate, pack.
- Convert an existing site with an agent - point an agent at a site you already have, and land it as an ordinary draft.
- Connect Claude over MCP - so you, or your client, can edit the draft from an assistant. Draft-first; publishing needs a human.
- Host it yourself - or let us host it. Both read the same published snapshot.
- Hand it to the client - invite them as an editor and decide what they may use. Note the one thing agencies get wrong: transferring workspace ownership voids every limit you set.
This reference is generated from the repo's internal docs (
docs/ARCHITECTURE.mdand friends). Code wins over docs - when they disagree, trust the code.
Didn't find the answer, or is something wrong here? Tell us.
Last updated on