Frontend

The Vue 3 law editor and library browser for working with machine-readable law.

The frontend is a law editor and library browser built with Vue 3 and Vite.

Overview

  • Framework: Vue 3 (Composition API)
  • Build tool: Vite 8
  • Design system: @nldd/design-system web components
  • Location: frontend/

Pages

Library

Browse the corpus of Dutch laws in a 3-pane layout:

┌──────────────┬──────────────┬──────────────┐ │ Law List │ Articles │ Detail │ │ │ │ │ │ Search & │ Filtered │ Text / │ │ filter laws │ articles │ Machine / │ │ │ │ YAML tabs │ └──────────────┴──────────────┴──────────────┘
  • Pane 1: All laws from corpus, searchable
  • Pane 2: Articles of selected law with favorites and filtering
  • Pane 3: Article detail with tabs for text, machine-readable view, and raw YAML

Editor

Edit law articles with a split-pane interface:

┌────────────────────────────────────────────┐ │ Document Tab Bar (open articles) │ ├──────────────────────┬─────────────────────┤ │ Legal Text │ Machine-Readable │ │ │ or YAML View │ │ With formatting │ │ │ toolbar │ Segmented control │ │ (bold, italic, │ to switch view │ │ lists, hr) │ │ └──────────────────────┴─────────────────────┘
  • Floating action sheet for editing operations and conditions
  • Law loaded from URL parameter (?law=...)

Design System

The frontend is built almost entirely from @nldd/design-system web components (custom-element prefix nldd-), imported one entry point at a time: src/main.js pulls in src/nldd-components.js, a generated list of exactly the components this app renders, plus the design system’s styles. script/check-nldd-imports.mjs keeps that list in sync with the tags in the source. A representative slice of the components in use:

CategoryComponents used
Layoutnldd-page, nldd-side-by-side-split-view, nldd-navigation-split-view, nldd-toolbar, nldd-spacer, nldd-container
Navigationnldd-top-title-bar, nldd-tab-bar, nldd-document-tab-bar, nldd-menu
Inputsnldd-search-field, nldd-text-field, nldd-multi-line-text-field, nldd-dropdown, nldd-combo-box, nldd-segmented-control
Lists & cellsnldd-list, nldd-list-item, nldd-text-cell, nldd-icon-cell, nldd-collection
Actions & overlaysnldd-button, nldd-icon-button, nldd-button-group, nldd-inline-dialog, nldd-modal-dialog, nldd-sheet
Contentnldd-rich-text, nldd-code-viewer, nldd-code-editor, nldd-title, nldd-tag

The Rijksoverheid brand color (#154273) and typography come from the design system; the only app-level stylesheet is frontend/css/main.css, which holds a handful of resets and one --color-primary token (the design system provides everything else through its own styles).

Vue components

The app is split into two top-level shells, LibraryApp.vue (the law browser) and EditorApp.vue (the split-pane editor), plus ~30 components under src/components/. Notable ones:

ComponentPurpose
ArticleText.vue / ArticleTextEditor.vueRender and edit article text
MachineReadable.vueMachine-readable visualization
YamlView.vueRaw YAML view
EditSheet.vue / ActionSheet.vue / OperationSettings.vueEditing operations and conditions
LawGraphView.vue (+ graph/)Cross-law dependency graph
ExecutionTraceView.vueExecution trace tree
ScenarioBuilder/Form/Gherkin/Visual/Panel.vueBDD scenario authoring
NoteCreator.vue / NoteCard.vueStand-off notes (RFC-018)
TrajectMenu.vue / TrajectMembersDialog.vueTraject collaboration

Composables hold the shared logic (useLaw.js for loading and article selection, plus others for settings and corpus URLs).

Data Loading

Law content comes from the editor-api over HTTP, not from static files. useLaw.js fetches and saves laws via lawUrl(...) (a GET to load, a PUT to save), with traject-scoped variants for private-repo collaboration. A scripts/copy-laws.js prebuild step still exists, but the runtime data flow goes through the API, so the editor can read and write the corpus.

Development

cd frontend npm install npm run dev # Start dev server on :3000

Or use the full dev stack:

just dev # Starts everything with hot reload

Deployment

The editor ships as a single Docker image (regelrecht-editor) that bundles the built Vue frontend together with the editor-api Rust binary, which serves the static assets and the REST API. It is deployed to RIG/ZAD:

  • Production: editor.regelrecht.rijks.app
  • PR previews: deployed for a pull request that carries the deploy:preview label

Corpusinwinning (harvester admin)

The harvester-admin dashboard is a section of this editor, at frontend/src/harvester/, not a separate app. It reaches the standalone packages/admin/ API through the editor-api /api/harvest-admin/* proxy, which forwards the shared session cookie so the admin service enforces its own harvester-* role gates. packages/admin/ is a Rust Axum API and serves no SPA of its own.

  • Features: Law status overview, job management, harvest and enrich triggers
  • Where: editor.regelrecht.rijks.app → Corpusinwinning

See Admin for the service itself.

See the admin API endpoints:

  • GET /api/law_entries - query law processing status
  • GET /api/jobs - query job queue
  • POST /api/harvest-jobs - create harvest job
  • POST /api/enrich-jobs - create enrich jobs
  • GET /api/jobs/{id} - job detail with progress

RegelRecht

An exploration by Bureau Architectuur of the Dutch Ministry of Economic Affairs and Climate Policy into the possibilities of transparent, executable legislation.

Links

GitHub repository
How it works
Stay informed
Roadmap (Dutch)
Documentation
Research

Contact

regelrecht@minbzk.nl

Part of

Bureau Architectuur
Ministry of Economic Affairs and Climate Policy