In Tussen de koffie en de inbox schreef ik dat de technische opzet van deze site een verhaal voor een ander blog was. Nou, dit is dat blog.

Van buiten ziet JeroenByDefault er rustig uit. Een paar verhalen, wat foto’s, Dribbel en Misty die ergens om de hoek kijken. Maar onder de motorkap gebeurt meer dan je zou denken. Ik werk in de IT, en dat merk je. Ik kan een website nu eenmaal niet bouwen zonder me af te vragen wat er misgaat als ik niet oplet.

Een tablet en een laptop 's avonds naast elkaar op tafel. Op de tablet staat de Engelse homepage van JeroenByDefault, op de laptop de code van die pagina in VS Code met rechts een AI-assistent
Links de site, rechts wat erachter zit.

Waarom geen WordPress

De voor de hand liggende keuze was WordPress geweest. Toch heb ik dat bewust niet gedaan. JeroenByDefault is een statische website: alle pagina’s worden van tevoren gemaakt en staan daarna als gewone bestanden klaar. Er draait geen database en er is geen beheeromgeving waar iemand op kan inloggen. Minder bewegende delen, dus ook minder dat kan breken of gehackt worden.

Je kunt het vergelijken met een boek dat al gedrukt is voordat je het openslaat. Op het moment dat je wilt lezen, hoeft niets meer bij elkaar gezocht of opnieuw gezet te worden. De pagina ligt gewoon klaar.

De site is gebouwd met Astro, een framework dat precies daarvoor bedoeld is. Ik schrijf mijn verhalen in Markdown, platte tekst met een paar simpele opmaaktekens. Astro maakt daar bij elke wijziging een complete website van. De code schrijf ik in TypeScript, een strengere variant van JavaScript. Dat maakt niet alle fouten onmogelijk, maar bij een flink aantal steekt de computer alvast zijn vinger op, nog voordat er iets live staat.

Opvallend vind ik hoe klein het geheel is. Naast Astro zelf gebruikt de site maar één uitbreiding, voor de sitemap. Voor het ontwikkelen en testen zijn er nog wat extra hulpmiddelen, maar die komen niet op de site terecht.

Een artikel is meer dan tekst

Bovenaan elk artikel staat een blokje met gegevens: titel, datum, taal, onderwerp en de foto’s met hun beschrijving. Astro controleert dat blokje bij elke build. Is een datum ongeldig, ontbreekt een beschrijving bij een foto of heeft een artikel geen vertaling? Dan stopt de build en gaat er niets live.

Dat klinkt streng, en dat is het ook. Maar ik weet zo zeker dat elke foto een beschrijving heeft voor mensen met een schermlezer. Niet omdat ik het elke keer onthoud, maar omdat de site het afdwingt.

Twee talen, één verhaal

De site is er in het Nederlands en in het Engels. Het Nederlands is leidend: daar begint elk verhaal, en de Engelse versie volgt. Een Engels artikel mag daarbij best een andere titel en webadres hebben. Een vaste sleutel in beide versies vertelt de site welke twee artikelen bij elkaar horen.

Wie de site in het Nederlands opent, ziet gewoon de Nederlandse homepage. Staat je browser op Engels, dan verschijnt bovenaan een kleine suggestie om naar de Engelse versie te gaan. Bewust een suggestie en geen automatische doorverwijzing. Ik vind het zelf irritant als een website voor mij bepaalt welke taal ik wil lezen.

Bovenaan de Nederlandse homepage van JeroenByDefault staat onder de menubalk een smalle balk met de tekst This site is also available in English en de links Read in English en Continue in Dutch
Een suggestie, geen doorverwijzing. Zo ziet een Engelstalige bezoeker de Nederlandse homepage.

Achter de schermen krijgen zoekmachines netjes door welke pagina’s elkaars vertaling zijn. En voor wie nog een RSS-lezer gebruikt, is er per taal een feed.

Statisch, maar niet stil

Een statische website klinkt alsof er niets kan bewegen. Dat valt mee. De pagina’s staan vooraf klaar, maar je browser kan daarna nog steeds iets doen. Op de artikelenpagina kun je zoeken en filteren op onderwerp. Dat gebeurt helemaal in je eigen browser, met de informatie die al op de pagina staat. Er gaat dus geen zoekopdracht naar een server.

Zet je JavaScript uit, dan blijven alle verhalen gewoon bereikbaar. Alleen de extra’s, zoals zoeken en het wisselen van thema, doen dan niet mee. Zo hoort het ook, vind ik: techniek mag iets toevoegen, maar een verhaal lezen moet altijd kunnen.

Licht, donker en de details

De site volgt de instelling van je apparaat: overdag licht, ’s avonds donker als je dat zo hebt ingesteld. Met een knopje in de header kies je zelf. Die keuze wordt toegepast voordat de pagina op je scherm verschijnt, zodat je ’s avonds niet eerst een witte flits in je gezicht krijgt.

Twee browservensters naast elkaar met dezelfde pagina Over mij van JeroenByDefault, links in het lichte thema en rechts in het donkere thema
Dezelfde pagina, licht en donker.

Foto’s zijn eigen werk of door AI gemaakt, en dat staat er dan ook gewoon bij. Ze zijn er in meerdere afmetingen en gebruiken WebP, een beeldformaat dat bestanden compact houdt. Je browser kiest een versie die past bij je scherm. Foto’s verderop in een verhaal laden meestal pas als je in de buurt komt. De eerste foto wordt meteen geladen, omdat die direct in beeld is.

Voor de koppen gebruik ik het lettertype Source Serif 4. Dat haal ik niet bij Google op, maar het staat gewoon op de site zelf, inclusief de licentie die daarbij hoort. De lopende tekst gebruikt het lettertype van je eigen apparaat. Dat leest prettig en kost geen extra laadtijd.

Er zitten meer van dat soort details in de code. Wie met het toetsenbord door de site gaat, ziet steeds duidelijk waar hij is. Heb je op je apparaat aangegeven dat je liever minder beweging op je scherm hebt, dan houdt de site daar rekening mee. Je ziet er geen aparte knop voor, maar het maakt wel verschil als je het nodig hebt.

En wie een artikel deelt in WhatsApp of op LinkedIn, ziet een eigen voorbeeldafbeelding per artikel. Klein detail, maar het ziet er een stuk verzorgder uit.

Geen tracking, wel een slot op de deur

In mijn werk gaat het vaak over governance: wie mag wat, waar staat je data en hoe houd je dat in de hand. Dat laat ik thuis blijkbaar niet achter.

Deze site volgt je niet. Er zijn geen advertenties, geen statistiekenpakket en geen knoppen van sociale media die stiekem meekijken. Er wordt niets bij andere partijen opgehaald, ook geen lettertypen of iconen. Je browser onthoudt alleen drie kleine dingen: je keuze voor licht of donker, je taalvoorkeur en of je de privacymelding hebt weggeklikt.

De opengeklapte privacymelding van JeroenByDefault in het donkere thema, met de uitleg dat je browser alleen je taal, je weergave en het sluiten van de melding onthoudt, en een knop Sluiten
Alles wat je browser onthoudt, staat gewoon in de privacymelding.

Daarnaast heeft elke pagina een Content Security Policy. Dat is een soort gastenlijst: de browser voert alleen code uit van de site zelf of code die op die lijst staat. GitHub Pages, waar de site draait, laat me die regels niet als serverinstelling meesturen. Daarom staan ze in de pagina zelf. Na elke build berekent een klein script een vingerafdruk van de scripts en stijlen die rechtstreeks in de pagina staan, en zet die op de lijst. Verandert zo’n stukje code zonder bijpassende vingerafdruk, dan blokkeert de browser het.

Ook de automatische processen op GitHub zijn vastgezet op een exacte versie, en een bot meldt elke week of er updates zijn. Ook zo’n update doorloopt eerst de controles voordat hij live komt.

Eerst testen, dan pas live

Hier wordt het een beetje gênant. Op het moment van schrijven staan er vijf verhalen op de site, maar er draait al een hele verzameling automatische controles. Ik slaap er wel rustiger door.

Alles staat op GitHub. Zodra ik een wijziging doorzet, gebeurt er dit:

  1. De code wordt gecontroleerd op fouten in Astro en TypeScript.
  2. De complete website wordt gebouwd, inclusief de beveiligingsregels.
  3. Een script controleert interne links, afbeeldingen en vertaalverwijzingen. Mist er iets, dan stopt alles.
  4. Een set tests controleert onder meer datums, vertalingen en de beveiligingsregels.
  5. Pas als alles groen is, zet GitHub de nieuwe versie live.
Overzicht van automatische controles op GitHub voor twee wijzigingsvoorstellen. Bijna alle runs hebben een groen vinkje, één browsertest heeft een rood kruis
Bijna alles groen. Dat ene rode kruis is een browsertest die een fout ving voordat die live kon gaan.

Bij voorstellen voor wijzigingen gaat er nog een stap overheen. Een automatische toegankelijkheidstest zoekt op een vaste set pagina’s naar problemen volgens de WCAG-richtlijnen, in licht én donker, op telefoonformaat en op een groot scherm. En een geautomatiseerde browser klikt door de belangrijkste onderdelen, zoals zoeken, filteren en de taalwissel. Links naar andere websites worden één keer per week nagelopen.

In oktober heb ik de hele site ook nog laten doorlichten. Daar kwamen een paar dingen uit die ik zelf nooit had gezien. De taalknop toonde “EN”, maar heette voor een schermlezer heel anders. Dat kan problemen geven als je met spraakbesturing “klik EN” zegt. En de grootste foto bovenaan een artikel werd juist later geladen in plaats van eerder. Allebei opgelost. Later volgde nog een ronde langs de richtlijnen van Apple en Google voor mobiel, zodat alles wat je kunt aantikken groot genoeg is voor een duim.

Gebouwd met AI, niet door AI

Eerlijk is eerlijk: ik heb deze site niet regel voor regel zelf getypt. Ik werk in VS Code en laat AI veel van het programmeerwerk doen. Eerst met Codex en een setje Grok-agents, elk met een eigen rol. Inmiddels doe ik het meeste met Claude Code, dat rechtstreeks in de repository meekijkt.

Wat ik wel zelf doe: bepalen wat er gebeurt. In de repository staat een bestand met projectinstructies voor de AI. Daarin staat bijvoorbeeld dat de site een persoonlijk logboek is en geen portfolio, dat er geen lettertypen van Google bij komen en dat Dribbel en Misty pluche knuffels zijn en geen echte honden. Je wilt niet dat een AI daar zelf iets bij gaat verzinnen. Het bestand voor het live zetten van de site mag de AI niet aanpassen. Publiceren doe ik zelf.

Elke wijziging komt in een logboek, met datum en uitleg. Zo kan ik later nog terugzien waarom een knop ineens groter werd. En de tests van hierboven zijn mijn vangnet. AI is snel, maar niet onfeilbaar. Een test die faalt, zegt het tenminste eerlijk.

Helemaal af is de site nooit. Onlangs kreeg hij nog een nieuwe vormgeving. Maar dat is misschien weer een verhaal voor een ander blog.

Wie verdwaalt, wordt opgevangen

Is dit allemaal nodig voor een persoonlijk blog? Waarschijnlijk niet. Maar het hoeft ook niet nuttig te zijn om leuk te zijn. Deze site is mijn logboek, maar ook mijn speeltuin. Een plek waar ik dingen uitprobeer die ik in mijn werk tegenkom, zonder dat er een klant op wacht.

En het mooie van alles goed regelen achter de schermen is dat je er aan de voorkant niets van merkt. Je leest gewoon een verhaal.

Tik je toch een verkeerd adres in, dan kom je niet op een kale foutmelding uit. Daar zitten Dribbel en Misty op je te wachten. Dribbel vindt dat hij die pagina persoonlijk bewaakt. Misty wijst je gewoon de weg terug naar huis.

Dribbel, een border collie met rugzak, leunt met vraagtekens boven zijn hoofd op stenen letters die 404 vormen, terwijl Misty, een husky, met haar poot de weg wijst over een bergpad
Wie verdwaalt, wordt opgevangen. (AI-gegenereerd)