- JavaScript 58.9%
- HTML 18.1%
- CSS 14.1%
- MDX 5.4%
- Nunjucks 3.4%
- Other 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .agents/skills/caveman | ||
| .github/workflows | ||
| .storybook | ||
| .vscode | ||
| _data | ||
| _includes | ||
| agent-os/standards | ||
| assets | ||
| container | ||
| docs/superpowers | ||
| inloggen | ||
| mailbox | ||
| mobu | ||
| moza | ||
| skills-internet@3e3184b4bf | ||
| stories | ||
| style | ||
| style-dictionary | ||
| tokens | ||
| .dockerignore | ||
| .eleventy.js | ||
| .eleventyignore | ||
| .gitignore | ||
| .markuplintrc.json | ||
| .pre-commit-config.yaml | ||
| .prettierignore | ||
| .prettierrc | ||
| .stylelintrc.json | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| index-pages.html | ||
| index.html | ||
| ontwerp-principes.md | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
MOZa proof of concept prototype
Zie Ontwerpprincipes voor de ontwerpprincipes, technische keuzes en relevante onderzoeken die ten grondslag liggen aan dit prototype.
Omgeving installeren
Clone deze repository lokaal.
Vereisten
Statische site-generator installeren
Eleventy wordt gebruikt om herhalende componenten zoals headers en footers als includes te beheren. Installeer Eleventy in de root van het project:
npm install @11ty/eleventy
Pagina's bouwen
Om de HTML pagina's te bouwen voer je dit commando uit vanuit de root van het project:
npx @11ty/eleventy
De gebouwde pagina's worden in de map _site geplaatst.
Lokaal bekijken
Start een lokale server met live reload:
npx @11ty/eleventy --serve
De site is vervolgens te bekijken op localhost:8080.
Includes
Herhalende componenten staan in de _includes map:
| Bestand | Beschrijving |
|---|---|
base.njk |
Basis layout |
header-rijksoverheid.njk |
Rijksoverheid header met logo en navigatie |
header-overheid.njk |
Overheid header header met logo |
footer-overheid.njk |
Overheid footer |
side-nav-overheid.njk |
Overheid hoofdnavigatie |
action-group.njk |
Actiegroep onder een topic (Bewaar, Deel, Niet relevant) |
Elke pagina selecteert diens layout en opties bovenaan het bestand:
---
layout: base.njk
title: "Pagina titel"
headerType: overheid
footerType: overheid
---
Design tokens
Design tokens zijn ontwerp-waarden — zoals kleuren, typografie, maatvoering — opgeslagen in een platformonafhankelijk formaat (JSON). Ze vormen een gedeelde taal tussen ontwerp en ontwikkeling: in plaats van bijvoorbeeld losse hex-codes of pixelwaarden door te geven, verwijzen beide disciplines naar dezelfde bron. Hierdoor blijven ontwerp en code altijd synchroon en is een wijziging op één plek (bijvoorbeeld een merkkleur) direct overal doorgevoerd.
Het bestand tokens/tokens.json is de single source of truth voor alle ontwerp-waarden én toepassingen (kleur, typografie, spacing, etc.). Dit bestand is in twee richtingen te bewerken:
- Figma; via de Tokens Studio plugin kunnen ontwerpers tokens ophalen, aanpassen en terugschrijven naar Git.
- IDE; ontwikkelaars kunnen het JSON-bestand ophalen, aanpassen en terugschrijven naar Git in een code-editor.
Style Dictionary
Om de design tokens te vertalen naar CSS variabelen wordt Style Dictionary gebruikt.
- Installeer Style Dictionary in
/style-dictionary, deze vertaald design tokens naar CSS variabelen - Instaleer SD-Transforms in
/style-dictionary, dit is een pakketje met extra transformatie-opties die nodig zijn om design tokens uit Figma Tokens Studio te vertalen
De pipeline ziet er zo uit:
Figma met Tokens Studio óf IDE → tokens/tokens.json → Style Dictionary + SD-Transforms → CSS variabelen → Stylesheet (style.css)
Style Dictionary leest tokens.json en transformeert de tokens naar CSS custom properties. Omdat Tokens Studio een eigen tokenformaat hanteert dat afwijkt van het standaard Design Token Community Group (DTCG) formaat, wordt SD-Transforms als aanvulling gebruikt. Dit zorgt onder andere voor het correct oplossen van tokenreferenties, het omrekenen van px naar rem waarden en het omzetten van namen naar ‘kebab-case’.
Het resultaat wordt opgesplitst in twee automatisch gegenereerde CSS-bestanden:
_rijkshuisstijl.css; bevat de waarden uit de Rijkshuisstijl: het kleurenpalet, typografie-instellingen, maatvoering, etc. Dit zijn de beschikbare opties._toepassing.css; bevat semantische variabelen die verwijzen naar de Rijkshuisstijl-waarden en daar een concrete betekenis aan geven, bijvoorbeeld--color-text-defaultof--button-primary-background-color. Dit zijn de toepassingen van de opties.
Gebruik in stylesheets en componenten altijd variabelen uit _toepassing.css en nooit rechtstreeks uit _rijkshuisstijl.css. De Rijkshuisstijl-variabelen zijn de bouwstenen; de toepassingsvariabelen bepalen hoe die bouwstenen worden ingezet. Door deze scheiding kan een Rijkshuisstijl-waarde wijzigen zonder dat stylesheets aangepast hoeven te worden, de toepassingslaag vangt de verandering op.
Beide bestanden worden automatisch gegenereerd en mogen niet handmatig bewerkt worden. Alle wijzigingen aan ontwerp-waarden horen thuis in tokens/tokens.json.
Design tokens vertalen naar CSS variabelen
Gebruik dit commando om design tokens handmatig naar CSS variabelen om te zetten:
npm run tokens
Dit resulteert in wijzigingen in de CSS variabelen bestanden. Deze worden automatisch geïmporteerd in de globale style.css style sheet.
Bij het gebruik van npm run dev worden design tokens automatisch opnieuw gebouwd wanneer tokens/tokens.json wijzigt.
Digitale Assistent
De chat-UI van de Digitale Assistent zit in dit prototype (moza/digitale-assistent.html + assets/javascript/digitale-assistent.js). De backend — een FastAPI-host die twee LLM-backends (VLAM en Claude) combineert met overheidsbronnen via MCP of CLI — leeft in een eigen repo en draait standalone:
→ https://github.com/MinBZK/moza-poc-digitale-assistent
Verbinden met de backend
In productie draait alles achter één origin: de nginx van de frontend proxyt de chat-endpoints (/chat, /chat/stream, /health, /tools) intern naar de backend. De browser praat dus alleen met de frontend-origin — geen CORS nodig, en de backend hoeft niet publiek te zijn. Twee instellingen:
| Variabele | Waar | Betekenis |
|---|---|---|
MOZA_CHAT_API |
build-time (_data/chatApi.js → base.njk → window.MOZA_CHAT_API) |
Waar de browser naartoe fetcht. Default leeg ("") = same-origin via de proxy. Productie laat dit leeg. |
BACKEND_ORIGIN |
runtime env op de nginx-container | Waar de proxy naartoe stuurt. Default http://dabackend:8000. Zet dit op het ZAD-component proef via de ZAD-UI (zad-actions/deploy kan geen runtime-env zetten). |
Lokaal end-to-end (zonder proxy; backend draait los, dus daar wél CORS):
npm run dev— Eleventy--serveoplocalhost:8080; zet automatischwindow.MOZA_CHAT_API=http://localhost:8000zodat de browser de lokale backend direct aanroept.- Start de backend (FastAPI, poort
8000) volgens de backend-repo. - Zet aan de backend
ALLOWED_ORIGINS=http://localhost:8080.
⚠️ Preview-deploys (
pr<nr>): het backend-componentdabackenddraait alleen in de gedeelde deployments (poc, gebruikersonderzoek), niet in per-PR previews. In een PR-preview is er dus geen backend en werkt de chat niet, tenzijdabackendaan die deployment wordt toegevoegd.
Voor losse demo's van de CLI-tools (
kvk-cli,koop-cli, …) gebruik je de backend-repo; die bevat de standalone bash-tools.
API-sleutels
Gebruikers kunnen hun eigen VLAM- en Claude-sleutel invullen via het feature-flags-paneel rechtsonder in de site. Deze worden per request als X-VLAM-API-Key / X-Claude-API-Key header naar de backend meegestuurd (de proxy laat die headers door). Dit werkt zolang de backend ALLOW_API_KEY_OVERRIDE=true heeft (PoC-default); lege velden vallen terug op de server-side keys.
Let op: een Claude-sleutel uit de UI werkt zelfstandig. Voor VLAM vraagt de UI alleen de sleutel, maar VLAM heeft ook
VLAM_BASE_URL+VLAM_MODEL_IDnodig — die moeten server-side op de backend staan. Het eenvoudigst is om de server-side keys op de backend-deployment te zetten, dan werkt de chat voor iedereen zonder iets in te vullen.
Containerisatie
De container/Containerfile bouwt de statische site (frontend-only): een Node-builder genereert de Eleventy-site en Storybook, en een nginx-image serveert die op poort 8080 én doet de same-origin reverse proxy naar de backend (zie Verbinden met de backend). De proxy-config (container/default.conf.template) wordt bij container-start gerenderd met envsubst; BACKEND_ORIGIN (runtime env, default http://dabackend:8000) bepaalt de upstream, met runtime-DNS-resolutie zodat nginx ook start als de backend nog niet up is. Dezelfde image (non-root, poort 8080) wordt gebruikt voor preview- en productiedeploys (ZAD).
docker build -f container/Containerfile -t moza .
# wijs de proxy naar een lokaal draaiende backend (Docker Desktop):
docker run --rm -p 8080:8080 -e BACKEND_ORIGIN=http://host.docker.internal:8000 moza
Storybook
Storybook is de omgeving om afzonderlijke componenten te bekijken, testen en documenteren.
Lokaal opstarten
npm run storybook
Storybook is vervolgens te bekijken op localhost:6006.
Automatisch bouwen
Bij het gebruik van npm run dev wordt Storybook automatisch opnieuw gebouwd naar _site/storybook wanneer bestanden in stories/ of style/style.css wijzigen. Dit gebeurt via chokidar die het build-storybook script triggert bij elke wijziging.
Stories
De stories staan in de stories/ map. Elk bestand beschrijft één component en toont varianten, bijvoorbeeld:
| Bestand | Beschrijving |
|---|---|
Knop.stories.js |
Knopvarianten (primair, secundair, negatief) |
Link.stories.js |
Linkvarianten |
Tekstinvoer.stories.js |
Tekstinvoervelden |
Selectie.stories.js |
Selectievakjes en keuzerondjes |
Feedback.stories.js |
Notificaties en foutmeldingen |
Navigatie.stories.js |
Navigatiecomponenten |
Typografie.stories.js |
Koppen en tekststijlen |
Tabel.stories.js |
Tabelopmaak |
NPM scripts
Installeer dependencies in de root van het project:
npm install
| Script | Commando | Beschrijving |
|---|---|---|
npm run dev |
Eleventy serve + token watcher | Beide parallel via concurrently. Eleventy --serve met live reload op localhost:8080; de chat-backend draai je apart (zie Digitale Assistent). |
npm run build |
Tokens + Eleventy | Volledige productie-build |
npm run tokens |
Alleen Style Dictionary | Handmatig tokens bouwen |
npm run storybook |
Storybook dev server | Componentenbibliotheek lokaal bekijken |
npm run build-storybook |
Storybook productie-build | Statische Storybook-site bouwen |
Structuur
📂 _data Eleventy-data: persona's, subsidies, regelgeving, berichtenbox
📂 _includes herhalende consistente elementen die in meerdere pagina's toegegepast worden
📂 _site statische site gegenereerd door Eleventy.js
📂 assets
📁 favicon favicons voor diverse platformen
📁 fonts Rijkslettertype webfonts
📁 icons iconen
📁 images afbeeldingen
📁 javascript interactielogica per pagina-type (personas, content-interactions, berichtenbox, etc.)
📂 container Containerfile + nginx-config voor de statische site-deployment
📂 mobu prototype voor MijnOverheid Burger
📂 moza prototype voor MijnOverheid Zakelijk, gebaseerd op deze omgeving
📂 stories 'stories' om componenten weer te geven in Storybook
📂 style
📄 _reset.css cross-browser stijl normalisatie
📄 _rijkshuisstijl.css opties uit de Rijkshuisstijl
📄 _toepassing.css semantische toepassing van de opties uit de Rijkshuisstijl
📄 style.css algemene CSS styling
📁 style-dictionary
📄 config.json configuratiebestand voor Style Dictionary
📁 tokens
📄 tokens.json design tokens JSON bestand
📄 .stylelintrc.json Stylelint-config (logical properties, alfabetische volgorde, spacing-regels)
📄 index.html homepagina van het MijnOverheid Zakelijk prototype
📄 package.json build dependencies
📄 package-lock.json locked dependency versions
📄 README.md dit bestand
CSS conventies
CSS patronen
Deze omgeving maakt gebruik van moderne CSS-features:
- CSS nesting voor o.a. component-staten en varianten
- CSS custom properties (variabelen) voor alle ontwerp-waarden
:focus-visible(niet:focus) voor toetsenbordfocus-indicatorenaria-disabledenaria-invalidARIA attributen voor staten (niet:disabled)
Variabele naamgeving
Gegenereerde variabelen volgen ‘kebab-case’ met een semantische hiërarchie:
--prefix-categorie-optionelesubcategorie-attribuut--optionelestaat
Voorbeelden:
--rijkhuisstijl-color-lintblauw-50--toepassing-button-primary-background-color
Logical properties
In de stylesheets worden CSS ‘logical’ properties gebruikt in plaats van ‘physical’ properties. Logical properties passen zich automatisch aan op basis van de schrijfrichting (direction) en schrijfmodus (writing-mode), wat de CSS toekomstbestendig en beter geschikt maakt voor meertalige ondersteuning.
Voorbeelden van physical properties en hun logical equivalenten:
| Physical | Logical |
|---|---|
width |
inline-size |
height |
block-size |
max-width |
max-inline-size |
min-height |
min-block-size |
margin-top / margin-bottom |
margin-block-start / margin-block-end |
margin-left / margin-right |
margin-inline-start / margin-inline-end |
padding-top / padding-bottom |
padding-block-start / padding-block-end |
padding-left / padding-right |
padding-inline-start / padding-inline-end |
border-top / border-bottom |
border-block-start / border-block-end |
Git commit berichten
Initial commit
Initiële commit, een eerste versie die in de bestandsgeschiedenis geplaatst wordt.
➕ Added
Toevoeging(en) aan een bestand.
Voorbeeld: ➕ Link component
✏️ Modified
Wijziging(en) aan een bestand.
Voorbeeld: ✏️ Kleur van :hover staat primaire knop
❌ Deleted
Verwijdering van (iets in) een bestand.
Voorbeeld: ❌ contactpagina.html verwijderd
🧼 Hygiene
Kleine aanpassing, fix.
Voorbeeld: 🧼 padding-inline-start → padding-inline
🐛 Bugfix
Herstel van een bug.
Voorbeeld: 🐛 footer include werd niet getoond
💾 Backup
Back-up van een bestand voordat grote wijzigingen plaatsvinden.
Voorbeeld: 💾 backup 2026-03-18 voorafgaand aan wijzigingen voor gebruikersonderzoeken
🔁 Renamed
Hernoeming van (iets in) een bestand.
Voorbeeld: 🔁 contact-pagina.html hernoemd naar comntact.html
↩️ Revert commit
Wijziging(en) in een vorige commit die ongedaan gemaakt worden.
Voorbeeld: ↩️ wijzigingen van vorige commit ongedaan gemaakt omdat deze performance issues veroorzaakte
🔀 IDE ↔︎ Figma
Twee-wegverkeer tussen IDE en Figma, met name om design tokens in beide omgevingen te kunnen aanpassen en testen (Style Dictionary → CSS variabelen en Figma Tokens Studio)
Voorbeeld: 🔀 tokens voor knoppen aangepast in Figma