Alle projecten
Experiment

Eén pagina goed bouwen, dertig klantsites eruit

Een sitebouwer voor bureaus waarin het compositiesysteem de beweging bewaart en de inhoud vrij laat.

De werkbank van Magicpage: links een paneel met de briefing en de knop Sweep images, rechts een oneindig canvas met drie pagina's van hetzelfde concept naast elkaar.
Product
Magicpage
Route
Nieuw product lanceren
Onderwerp
Gereedschap voor makersDesign systemsGeneratieve media
Platform
Web
Jaar
2026

Een bureau maakt niet één website maar dertig, en bij elke daarvan wordt dezelfde afweging opnieuw gemaakt: waar begint de tekst, hoe komt dat beeld binnen, waar valt de naad tussen twee secties. Magicpage draait dat om. De blokken zeggen alleen wat ze zijn, het systeem beslist wat er gebeurt, en de choreografie die je één keer goed hebt gezet begint bij de volgende klant weer van voren af aan.

Gebouwd met
  • TypeScript
  • React 19
  • Next 15
  • GSAP
  • CSS Cascade Layers
  • Cloudflare Pages
  • pnpm-workspace
Cijfers

In het kort

commits
317
sprints
58
blokken
110
poorten
14
combinaties gecontroleerd
440
De opgave

Wat er lag

Een bureau maakt niet één website maar dertig, en bij elke daarvan wordt dezelfde afweging opnieuw gemaakt: waar begint de tekst, hoe komt dat beeld binnen, waar valt de naad. Bestaande bouwers geven je een template, en zodra je ervan afwijkt valt het uit elkaar. De opgave: de choreografie één keer vastleggen en de inhoud vrij laten. Eén pagina goed bouwen, en de volgende klant daarvandaan beginnen.

Hoogtepunten

Drie details die het verschil maken

Het verhaal

Hoe het is gemaakt

Het probleem was niet “een site maken”

Een bureau maakt er dertig, en bij elke daarvan wordt dezelfde afweging opnieuw gemaakt: waar begint de tekst, hoe komt dat beeld binnen, waar valt de naad tussen twee secties. Dat is het dure deel, en het is bij elke klant grotendeels hetzelfde.

Bestaande bouwers lossen daarom het verkeerde probleem op. Ze geven je een template, een afgewerkt ontwerp waar je content in giet, en zodra je ervan afwijkt valt het uit elkaar. Wat je wilt is het omgekeerde: de choreografie vastleggen en de inhoud vrij laten.

Magicpage is daarom gebouwd rond een compositiesysteem, en pas daarna rond pagina's. Je maakt één keer een pagina zoals je hem wilt hebben, legt hem vast, en begint de volgende klant daarvandaan: andere blokken, ander merk, andere tekst, dezelfde beweging.

Blokken blijven dom

Elk blok zegt alleen wat het is, of hoe het zich verhoudt tot zijn buurman. Het systeem beslist wat er gebeurt. Een blok noemt zijn kop een kop en de overgang naar het volgende blok een band; welke beweging daarbij hoort en hoe die band eruitziet staat ergens anders. Dat klinkt als een detail en het is de hele architectuur.

Daarom kan één regel in een bewegingsset alle honderdtien blokken veranderen, en hoeft een nieuw blok niets van beweging te weten. Bij elk nieuw idee is dat de toets, en hij heeft in drie maanden meer beslissingen genomen dan welk overleg dan ook.

Eronder ligt een cascade van vijftien CSS-lagen in één declaratie, en die volgorde is geen smaak: hoofdstukken komen ná de doorlopende beweging omdat hoofdstukruimte marge is die bovenop alle voorgaande afstanden komt, en de viewport-laag komt daar weer achter zodat een schermregel altijd het laatste woord heeft. Elke positie in die rij is één keer beargumenteerd en staat in de code uitgeschreven.

Kan het blok het benoemen zonder het uit te voeren?

De lus die het product ís

Alles hierboven bestaat voor één werkgang. Bouw één maximale pagina (dertien blokken, vijf hoofdstukken, gemeten overgangen) en leg hem vast als sjabloon. Niet een gekocht ontwerp maar jouw concept: alle pagina's met hun choreografie, plus merk en art directie. Dat is het dure werk en je doet het één keer.

De volgende klant begint daarvandaan. Je wisselt de blokken, en de naden, hoofdstukken en scènes blijven staan. Je herbrieft de inhoud: wat het bedrijf doet, voor wie, wat het onderscheidt. En dan gaat er één beeld-sweep over de hele site.

Dat werkt in concepten, de tabs bovenin de werkbank: varianten van dezelfde site die je naast elkaar aan een klant laat zien. Elk concept heeft zijn eigen pagina's op één oneindig canvas, dus je bladert niet door schermen maar zoomt uit.

Die laatste stap is het principe in het klein. Een blok vertelt al alles wat een beeldbriefing nodig heeft: dat dit slot een beeld wil, wat voor beeld (het pad ernaartoe zegt dat een avatar een portret is), welke verhouding, wat het onderwerp is (de kop van het blok) en welke art directie eroverheen ligt. Je hoeft het alleen op te rapen. Dus geen promptveld erbij, maar: het systeem stelt de briefing op en jij corrigeert hem.

Toen deden we de telling die de aanpak bevestigde. Tweeëntwintig beeldslots zitten in blokken die zichzelf als beeldblok aankondigen, en honderdvier daarbuiten: avatars in testimonials, teamrasters, blogcovers. Alleen op die aankondiging afgaan had vijf zesde van de beelden overgeslagen.

Een gepubliceerde pagina uit Magicpage: schermvullend beeld van een hand die een boek uit een volle kast trekt, met daaroverheen het label “New collection” en de kop “Something that feels big”.
Wat eruit komt is statische HTML met de CSS ingesloten en de beweging als los, gedeeld bestand: 227 kilobyte per pagina. Het beeld hier is door het systeem gebrieft uit wat het blok al zei.

Veertien poorten tegen stille fouten

Elke poort in dit project is ontstaan uit één concrete fout die stil was. Geen foutmelding, geen rode build, alleen een pagina die er “gewoon anders” uitzag. Dat is de duurste soort, want je vindt hem pas als een klant kijkt.

Er staan er nu veertien: een poort die controleert dat het paneel alleen scènes aanbiedt die een blok kán dragen, een die kijkt of elk gevonden beeldpad ook wordt teruggeschreven, een die merkkleuren betrapt die bij het publiceren stil wegvielen, een die nakijkt of elk formulier post naar iets dat bestaat.

De jongste is meteen de mooiste. De keuzeruimte is elf thema's maal acht interfacesets maal vijf bewegingssets: vierhonderdveertig combinaties, waarvan er ooit vijf met het oog bekeken waren. Die poort rendert ze nu alle vierhonderdveertig en controleert dat de CSS die ze gebruiken ook meekomt, en dat het onder de negenhonderd kilobyte blijft. Vier seconden voor de hele set, want React is na de eerste render warm.

Geleerd

Wat we eruit hebben geleerd

  1. 01

    Het meest voorkomende defect in dit project was een afwezigheid: acht keer was er iets gebouwd, getest, en werd het door niets aangeroepen. Compositielagen die nergens werden gezet. Scènes die het paneel niet aanbood. Een veld met veertien lezers en geen enkele schrijver. Het patroon is verraderlijk omdat alles groen is: de code compileert, de test slaagt, het ding bestaat, en alleen doet het niets. “Wie roept dit aan?” is de goedkoopste vraag die er is en we stelden hem het minst.

  2. 02

    Drie keer stelden we voor iets te schrappen omdat het zeldzaam was, en drie keer klopte dat niet. Formulieren kwamen in geen enkel sjabloon voor, maar een site zonder werkend contactformulier is geen site. Frequentie meet blootstelling in de data die je toevallig hebt; het meet niet wat het ding doet. De vraag is niet hoe vaak iets voorkomt maar wat je verliest als het weg is.

  3. 03

    Drie knoppen logen. Een knop die na twee seconden “geverifieerd” zei, ongeacht wat er in de DNS stond. Een contactformulier dat op drie verschillende manieren “Verzonden!” teruggaf terwijl er niets verzonden werd. De venijnigste had een keurige try/catch. Alleen gooit die bibliotheek niet bij een fout van de dienst, hij geeft het resultaat mét een foutveld terug. De catch ving dus alleen netwerkfouten, en een geweigerde sleutel gleed er zo langs. Een knop die liegt kost je pas iets op het moment dat je erop vertrouwt, en bij een contactformulier is dat een gemiste klant.

  4. 04

    En meet eerst je meetopstelling. Een halve dag ging op aan “deze functie werkt niet”, terwijl we aan het meten waren in een verborgen browserpaneel: daar is de pagina officieel onzichtbaar en tikt de tekenlus niet, dus alles wat op beweging wacht staat stil. Het pijnlijke was dat dit al opgeschreven stond van een eerdere sprint, waar screenshots zwart bleven om dezelfde reden. Een meting die je niet begrijpt is eerst verdacht op zichzelf, en pas daarna op het ding dat je meet.

Ontwerp

Letters en kleuren

Letters
Koppen en tekst
Inter VariableEén variabele familie voor alles in de werkbank; de sites die eruit komen dragen hun eigen letters.
Code en velden
JetBrains MonoVoor paden, sleutels en alles wat je kopieert.
Kleuren
  • Grond
    #f1f0ee
    de achtergrond van de werkbank
  • Vlak
    #ffffff
    panelen en kaarten
  • Verzonken
    #e4e2df
    een spoor waar een control in ligt
  • Inkt
    #0a0a0b
    tekst
  • Violet
    #6544fc
    het ene accent: de knop en de actieve tab
  • De werkbank is grijs en het accent violet, zodat de site van de klant in het canvas de enige kleur is die telt.
  • Kleur in een gebouwde site wordt niet per thema uitgeschreven maar afgeleid: één basisvlak en één basisletter voeden vier sporten van een ladder.
  • De waarden komen uit de tokens in de code, 7 september 2026.
Techniek

Waar het van gemaakt is

  • Bouw
    • TypeScript
    • React 19
    • Next 15
    • GSAP
    • pnpm-workspace

    Zes packages in één workspace: 112.500 regels TypeScript en 18.500 regels CSS in 58 sprints, door één ontwikkelaar.

  • Compositie
    • 15 CSS-cascadelagen
    • 110 blokken
    • 128 CSS-delen

    Blokken zeggen wat ze zijn; het systeem beslist wat er gebeurt. Elke laag in de cascade is één keer beargumenteerd.

  • Poorten
    • 14 poorten
    • 440 combinaties
    • Vier seconden

    Elke poort ontstond uit één fout die stil was; de jongste rendert alle combinaties en controleert of de CSS meekomt.

  • Uitvoer
    • Statische HTML
    • CSS ingesloten
    • Eén gedeeld motion-bestand
    • Cloudflare Pages

    227 kilobyte per pagina; de CSS blijft inline omdat die het tekenen blokkeert, de beweging niet.

Verdieping

Voor wie verder wil lezen

Onder de motorkap

TypeScript, React 19, Next 15 en GSAP, zes packages in één pnpm-workspace, uitgerold op Cloudflare Pages.

TypeScript, React 19, Next 15 en GSAP, zes packages in één pnpm-workspace, uitgerold op Cloudflare Pages. 112.500 regels TypeScript en 18.500 regels CSS, in drie maanden en achtenvijftig sprints, door één ontwikkelaar. Honderdtien blokken, honderdachtentwintig CSS-delen.

Twee technieken zijn het waard om mee te nemen. Kleur wordt niet per thema uitgeschreven maar afgeleid: één basisvlak en één basisletter voeden vier sporten van een ladder, en elk kleurschema leidt daar zijn gronden uit af. Dat werkt vanzelf de goede kant op, licht of donker. En de overgang van een portfoliokaart naar de case-pagina die hij opent gebeurt zonder één regel JavaScript: de browser doet dat zelf, mits de naam die de twee aan elkaar knoopt uniek is binnen één document. Een case-pagina die zichzelf toonde in haar eigen “meer werk”-raster had hem twee keer, en sloopte de hele overgang.

De motion-runtime stond eerst inline in élke pagina: 159 kilobyte, zes keer hetzelfde. Nu is het één gedeeld bestand. De CSS blijft wél inline, en dat verschil is de hele afweging: CSS blokkeert het tekenen, beweging niet.

Wat er open staat

Een eerlijke case noemt ook wat er niet af is.

Een eerlijke case noemt ook wat er niet af is. Er is nog nooit uitgerold. Het hele pad tot en met de bestandenset is gemeten, het uploaden zelf niet. Eén echte uitrol toetst in één keer drie dingen die nooit gedraaid hebben.

Hoe die vierhonderdveertig combinaties eruitzien weten we ook niet. De poort controleert dat de CSS meekomt, niet dat de combinatie mooi is. Dat vraagt ogen, geen script.

En video. Dezelfde beeldbriefing, andere modaliteit, maar met wachttijden in minuten in plaats van seconden. Dat vraagt een taak met een wachtrij, en dát is de kostenpost, niet de aanroep zelf.

Voor wie is dit?

Voor een bureau dat niet één website maakt maar dertig, en bij elke daarvan dezelfde afweging opnieuw maakt.

Wat is een sjabloon hier?

Jouw eigen concept: alle pagina's met hun choreografie, plus merk en art directie. Niet een gekocht ontwerp waar je content in giet.

Hoe komt het beeld erin?

Een blok vertelt al alles wat een beeldbriefing nodig heeft; het systeem stelt de briefing op en jij corrigeert hem. Eén sweep over de hele site.

Is het al uitgerold?

Nee. Het hele pad tot en met de bestandenset is gemeten, het uploaden zelf niet. Eén echte uitrol toetst drie dingen die nooit gedraaid hebben.

Wat weten jullie nog niet?

Hoe de vierhonderdveertig combinaties eruitzien. De poort controleert dat de CSS meekomt, niet dat de combinatie mooi is. Dat vraagt ogen, geen script.

Meer werk

Lees ook

De oprichter van een filmstudio voor de ledwand met een zonsondergang, een laptop onder zijn arm.

Een halfuur gratis sparren over jouw digitale idee?

Waar loop jij tegenaan in je bedrijf? Wat kan beter? Wat kan sneller? Wat gaat nog met de hand en moet nodig geautomatiseerd worden?

  • Een halfuur sparren over jouw idee, gratis
  • Je weet direct welke route je nodig hebt
  • Ruwe inschatting over de prijs en het aantal weken
Wat is jouw idee?

Een alarm op onze spreadsheet dat appt zodra een getal buiten de marge valt.

administratiekantoor, Sneek

Alexander Kaan, zwart-witfoto.

Vertel me je probleem, je geniale idee of stel gewoon wat vragen!

Alexander Kaan · Product Designer