Korte versie
We bouwden deze site zonder CMS. Alle content leeft als MDX- en JSON-bestanden in Git en Astro Content Collections valideren elk veld bij de build. Dat scheurt een hele laag weg: geen API-calls, geen database, geen accounts voor editors, geen plugin-onderhoud. De publicatie is een gewone commit en deploy. Voor AI-agenten is zo'n repo een natuurlijke werkplek: lezen, schrijven en reviewen gebeurt met bestandsoperaties die een agent al beheerst. Hier lees je hoe de architectuur eruitziet, wat het opleverde en wanneer je tóch beter een CMS kiest.
Deze website heeft geen CMS. Geen Storyblok, geen WordPress, geen database met berichten. Alles wat je leest staat als MDX- en JSON-bestanden in een Git-repository, en Astro Content Collections valideren bij elke build elk veld tegen een schema. Dit artikel is zelf zo’n bestand: frontmatter bovenaan, daaronder secties in getypeerde blokken.
Waarom zou je een website zonder CMS willen? Omdat een CMS voor een statische site met een klein team vaak meer kost dan het oplevert. Niet alleen in euro’s, maar in onderhoud, veiligheidsoppervlakte en de extra laag tussen “tekst klaar” en “pagina live”. Toen we de afweging maakten, bleek dat we de meeste CMS-functies niet gebruikten en het benodigde contentbeheer met Git-conventies konden vervangen. Boven verwachting bleek ook dat de architectuur de beste werkplek is die je een AI-agent kunt geven.
In dit artikel leg ik uit hoe wij het aanpakten: welke rol Content Collections spelen, hoe de content in Git is georganiseerd, wat het opleverde en wanneer je tóch beter voor een CMS kiest.
Waarom wij het CMS afstootten
Vóór de zomer van 2026 draaide deze site nog op Astro mét Storyblok. Een prima combinatie, technisch netjes, en voor klanten bouwen we die stack vandaag nog steeds. Maar voor onszelf groeide de frictie.
Een CMS meenemen betekent in de praktijk dat je veel regelt wat niets met content te maken heeft:
- een space met componenten en contentmodellen die gelijk moest lopen met de code;
- API-calls in de build die faalden als het CMS een stootje kreeg;
- accounts en rechten voor iedereen die iets wilde aanpassen;
- webhooks of rebuilds om publicaties vlot te trekken.
En er was een tweede plek waar “de waarheid” leefde. De repository bevatte de code, het CMS bevatte de inhoud. Elke wijziging moest je in beide werelden begrijpen.
De vraag die het deed kantelen was simpel: wie werkt er eigenlijk met deze content? Het antwoord: Seppe en het team, plus de AI-agenten die het voorbereidende werk doen. Niemand van ons heeft een grafische editor nodig. Iedereen in die groep leest en schrijft al dagelijks in Git. Het CMS was een vertaallaag tussen twee groepen die dezelfde taal spraken.
Daar komt bij dat de agenten toegang tot het CMS nodig hadden om inhoud te kunnen aanpassen. API-sleutels, een MCP-server als brug, rate limits en draft-workflows: allemaal oplosbare dingen, maar allemaal extra bewegende onderdelen om te beheren en te beveiligen. In Git waren die problemen gewoon weg. De agent leest een bestand, past het aan en maakt een diff, exact wat een agent van nature doet.
De kern van de wissel
Een CMS lost het probleem “hoe krijgen niet-technische mensen content in een website” op. Wij hebben dat probleem niet. Wij hebben het probleem “hoe houden we een groeiende site snel, veilig en door AI-agenten beheerbaar”. Voor dat tweede probleem is een Git-repository met getypeerde content een directer antwoord.
Wat Astro Content Collections zijn (en wat niet)
Astro Content Collections zijn de ingebouwde contentlaag van het framework: een collectie is een set gelijksoortige content met dezelfde structuur, en elk bestand daarin heet een entry. Je wijst per collectie een loader en een schema aan. Astro laadt bij de build alle bestanden als getypeerde entries en controleert ze tegen dat schema. Zo staat het ook in de officiële Astro-documentatie over content collections, die ze de beste manier noemt om sets content in een Astro-project te beheren.
Wij hebben er zes: pagina’s en artikelen als MDX, en datasets, case-metrics, mensen en instellingen als JSON.
Zo ziet de configuratie er in ons project uit, ingekort tot het principe:
import { defineCollection } from 'astro:content';
import { glob } from 'astro/loaders';
import { articleFrontmatterSchema } from './content/schemas/article';
const articles = defineCollection({
loader: glob({ pattern: '**/*.mdx', base: './src/content/articles' }),
schema: articleFrontmatterSchema,
});
export const collections = { articles /*, pages, datasets, … */ };Het schema is een Zod-definitie die precies vastlegt welke velden een artikel mag en moet hebben: titel, route, publicatiedatum, auteur, categorie, tags, samenvatting, FAQ-items. Is de frontmatter van één bestand onvolledig of zit er een typo in een veldnaam, dan faalt de build met een foutmelding die het bestand en het veld benoemt. Voor je bezoekers verandert er niets: de output is gewone, snelle HTML.
Wat het dus wél is: een contract tussen je content en je templates. Elk artikel dat de template inleest, heeft gegarandeerd de velden waar de layout op rekent. Dat geldt ook voor de JSON-datasets die we aan cards en onderdelen meegeven: het zijn dezelfde schema’s, dezelfde garanties.
En wat het níét is: een CMS. Er is geen grafische editor, geen database, geen preview-omgeving met inlogscherm, geen API-token die kan verlopen. Content Collections vervangen niet de editor-ervaring van Storyblok of WordPress; die bestaat hier gewoonweg niet. Wie dagelijks content wil slepen en schuiven in een vertrouwd dashboard, voelt dat gemis meteen. Daarover meer in de sectie over wanneer je tóch een CMS kiest.
Wil je eerst de bredere context: wat een CMS is en hoe een headless CMS werkt, leggen we apart uit in de kennisbank.
Hoe onze architectuur eruitziet: MDX en JSON in Git
De hele inhoudelijke structuur van de site leeft in één repository. Dit is de organisatie in het kort:
src/content/
├── pages/ # landingspagina's en hubpagina's (MDX)
│ ├── nl/ # Nederlandstalige pagina's
│ └── en/ # Engelse pagina's
└── articles/
├── nl/
│ ├── blog/ # blogs
│ ├── case/ # cases
│ └── begrippen/ # begrippen
└── en/
├── blog/ # blogs
├── case/ # cases
└── glossary/ # begrippen(Datasets, case-metrics, mensen en instellingen leven als JSON ernaast; de boom hierboven toont de MDX-zijde.)
Elk bestand begint met frontmatter die aan het schema moet voldoen. De frontmatter van dit artikel bevat onder meer de route, de auteur, de samenvatting voor de “korte versie”, de FAQ voor onderaan de pagina en de referentie naar het beeld hierboven. Onder die frontmatter staat de body: gewone Markdown-headers binnen getypeerde sectiecomponenten. Interne links schrijven we als gewone links; de URL-conventie zonder trailing slash bewaakt de build zelf.
Daar zit de kern van wat Git hier sterker maakt dan een CMS. Elke inhoudelijke wijziging is een diff: je ziet welke regel in welk bestand veranderde, wanneer, door wie, en waarom in de commitmessage. Een nieuwe blog publiceren is een commit op de hoofdbranch; Vercel bouwt en deployt automatisch. Terugdraaien kan met een revert. Er is geen tweede systeem om te synchroniseren en geen versie in het CMS die kan afwijken van de code die hem rendert.
Diezelfde structuur zetten we onszelf ook bewust strak. De site is tweetalig, en de Engelse tegenhangers zijn via een vast paarregister gekoppeld aan de Nederlandse pagina’s. Omdat de koppeling in de repository leeft, kan de buildcontrole controleren dat elke koppeling naar een echte route wijst en dat beide kanten elkaars bestaan bevestigen.
| Criterium | Klassiek CMS | Headless CMS | Content in Git |
|---|---|---|---|
| Waar leeft content | Database van het CMS | Database achter een API | Bestanden in de repository |
| Wie past content aan | Editors in het dashboard | Editors in het dashboard | Iedereen met schrijfrechten op Git |
| Validatie | Veldcontrole in het CMS | Veldcontrole in het CMS | Schema bij de build, faalt hard |
| Publicatie | Opslaan in het CMS | Opslaan en rebuild | Commit en push, deploy volgt |
| Versiegeschiedenis | Revisions in het CMS | Revisions in het CMS | Volledige diff per wijziging |
| Extra onderhoud | Core, plugins, database | API, accounts, webhooks | Alleen de repository zelf |
| Runtime-afhankelijkheden | Server en database | CMS-hosting en API | Geen, de site is statisch |
| AI-agent-toegang | Plugin of API-rechten | MCP-server of API-sleutel | Gewone bestandsoperaties |
Kort samengevat: content in Git wint op validatie, versiegeschiedenis en AI-toegang, een CMS wint op de editor-ervaring voor niet-technische teams. De laatste rij is voor ons de belangrijkste geworden, en verdient een eigen sectie.
Waarom AI-agenten hier van profiteren: Git als werkplek
In 2026 is de manier waarop AI-agenten werken snel volwassen geworden. Ze lezen instructiebestanden, verkennen een projectstructuur, voeren commando’s uit en passen bestanden aan. Publicaties over deze evolutie beschrijven hetzelfde patroon, zoals het GitHub-blog over AGENTS.md en artikelen over Markdown in het AI-tijdperk. Agenten presteren het best in repositories vol platte, gestructureerde tekst.
Onze eigen AI-agent Hermes werkt zo ook. Voor elke contenttaak leest Hermes instructies en schema’s, zoekt de relevante bestanden op, past ze aan en laat de build de validatie doen. In een CMS-wereld heeft zo’n agent een brug nodig naar het CMS: API-sleutels, een MCP-server met de juiste rechten, rate limits, draft-statussen. In de Git-aanpak leest en schrijft de agent gewoon bestanden.
CloudCannon, een CMS-leverancier die beide werelden aanbiedt, formuleerde het in 2026 zo: hoe meer content je hebt, hoe meer een agent moet ophalen en parsen via een API, terwijl een lokaal bestand lezen gratis is. Hun conclusie voor AI-gedreven teams was ronduit dat git-based content wint.
Vier concrete voordelen, zoals wij ze elke dag ervaren:
- Lezen kost geen API-verkeer. De agent opent het MDX-bestand en ziet in één oogopslag frontmatter, structuur en inhoud. Geen endpoint-calls, geen rate limits, geen vertaalwerk van API-respons naar tekst.
- Schrijven is een gewone bestandsoperatie. Een sectie herschrijven, een FAQ-item toevoegen, interne links bijwerken: het gebeurt met dezelfde tools als codebewerking. Er is geen CMS-specifieke API om te leren of te beveiligen.
- Elke wijziging is een diff. Voor een mens is dat de natuurlijke reviewvorm: je leest de diff, keurt hem goed en commit. Je hoeft niet te vertrouwen op de logging van een CMS om te reconstrueren wat een agent deed.
- De build is de kwaliteitspoort. Doordat het schema hard faalt, kan een agent geen inhoud publiceren die niet aan het contract voldoet. Verkeerde datumnotatie, ontbrekend veld, te lange samenvatting: de build stopt en wijst naar het bestand. Hoe AI de dagelijkse kwaliteitscontroles doet, lees je in hoe we onze blog met AI optimaliseren.
Belangrijk is waar de grens ligt. De agent bereidt voor en voert controles uit; wat er gepubliceerd wordt, beslissen mensen. Dat is bij ons een bewuste afspraak, geen technische noodzaak. Zonder die discipline is een AI-agent met schrijfrechten op een repository precies zo riskant als een agent met publicatierechten in een CMS.
Wat het opleverde: meten, niet beweren
Cijfers over een eigen migratie zijn pas iets waard als je ze ook echt meet. Deze site behandelen we daarom als een lopende case: maandelijkse PageSpeed-metingen en maandelijkse Search Console-data, publiek inzichtelijk op de casepagina van Straffe Sites.
Over de volledige maand september 2026 ziet die meetreeks er zo uit (mobiele PageSpeed-labmetingen, per site de beste meting van de maand, snapshot van 9 oktober 2026):
| Meting | Resultaat | Basis |
|---|---|---|
| Performance van straffesites.com | 100/100 | Beste mobiele meting van september |
| Lab-LCP in diezelfde meting | 1,4 seconden | Zelfde meting als de score |
| Mediaan van de twaalf andere casesites | 100/100 | Beste mobiele score per site |
| Snelste Lab-LCP over alle dertien sites | 0,9 seconden (924 ms) | Snelste meting van de maand |
Zeven van de twaalf andere casesites haalden in september minstens één keer 100/100. Dat zijn metingen van echte productiesites, geen demo’s. Het blijven wel labmetingen: ze zeggen niets over de ervaring van elke bezoeker.
Die cijfers komen niet uit de lucht gevallen en zijn ook geen automatisch gevolg van “geen CMS”. Ze komen van de lichte technische basis die deze aanpak afdwingt: statisch renderen en bijna geen JavaScript. De build laat bovendien niets door wat niet aan de schema’s voldoet. Zonder database en API-laag zijn er wel minder bewegende onderdelen die je snelheid en stabiliteit kunnen breken.
De grootste winst zit niet in de cijfers, maar in het werk zelf. Een site zonder CMS-onderhoud is een site met één zorgpunt minder. Sinds de wissel is er geen CMS-update meer gepland, geen plugin-audit meer gedaan, geen API-key meer geroteerd en geen CMS-account meer beheerd. Het enige dat nog telt, is de repository: één plek, één geschiedenis, één set regels. Hoe groot dat verschil is, bleek op 21 oktober 2026: toen veel websites uit voorzorg offline gingen door een lek in PHP, viel er op deze statische site niets te patchen.
Wanneer kies je tóch een CMS?
Deze aanpak is geen wet. Ze past bij een specifieke situatie, en het is eerlijk om die grens te benoemen.
Kies een CMS als je team niet in Git werkt. Een grafische editor, conceptstatussen, rechtenbeheer en publicatieflows: dat zijn precies de problemen waarvoor CMS’en gebouwd zijn, en ze lossen die goed op. Voor veel bedrijven met een marketingteam dat wekelijks content plaatst, is een dashboard onmisbaar.
In die situaties bouwen we ook oplossingen mét CMS, zoals headless met Storyblok. Er bestaat ook een tussenweg: een git-based CMS met een grafische editor die onder de motorkap naar Git schrijft. De editor-ervaring blijft, de voordelen van bestanden ook. Decap CMS, Keystatic en TinaCMS zijn voorbeelden; de Astro-gids over CMS-koppelingen zet ze naast de API-gedreven systemen. Twijfel je tussen beide routes, dan beschrijven we de commerciële kant van zo’n architectuur op de pagina over headless websites laten bouwen.
Kies ook een CMS als je contentstructuur vaak en snel verandert door mensen buiten het ontwikkelteam. Nieuwe contenttypes bedenken hoort bij een dashboard met veldbeheer; in onze aanpak is een nieuw contenttype een schema- en templatewijziging, ontwikkelwerk dus.
En kies een CMS als je functies nodig hebt die van het CMS afhangen: ingebouwde mediabibliotheken met gebruikersrechten, geplande publicaties, vertaalworkflows per veld of koppelingen met andere systemen via het CMS. Je kunt dat allemaal in Git nabouwen. Maar dan bouw je zelf een mini-CMS, en dat wilden we net vermijden.
De vraag is dus niet “is een CMS slecht?”, maar “wie werkt er dagelijks met je content?”. Is dat een technisch team dat toch al in Git leeft en AI-agenten inzet, dan is content in Git de directere weg. Is dat een redactie met niet-technische mensen, dan is een CMS de juiste tool en is er niets mis met die keuze. Hoe je headless en klassiek naast elkaar zet, lees je in headless CMS of klassiek CMS, en voor een concrete systeemvergelijking bestaat er Storyblok vs WordPress.
Twijfel je of een website zonder CMS past bij jouw team en plannen? Dan helpt een kort gesprek meer dan nog een artikel lezen. Bespreek je project. Wil je eerst zien hoe wij zo’n site concreet bouwen, dan beschrijft de pagina over een Astro-website laten bouwen onze aanpak. En wil je weten met wie je daarover praat? De pagina over deze freelance webdeveloper beschrijft hoe ik techniek, snelheid en vindbaarheid in één spoor aanpak.

