Accessibility (WCAG / EN 301 549)
Dutch government bodies must make their websites and apps meet EN 301 549, which references WCAG 2.1 level AA, and publish a toegankelijkheidsverklaring (accessibility statement) in the national register. This covers the public pages a municipality puts in front of citizens (forms, booking, polls, signing) and also the intranet/extranet their staff use, meaning the whole Goooy web app.
This page records what is verified, how, and what is not yet. It is the input for a municipality’s statement, not the statement itself; for that see toegankelijkheidsverklaring-model.md.
How it is tested
| What | How | Where |
|---|---|---|
| Every module’s landing view, all 21 admin tabs, the mail composer, the event, contact and search dialogs, a Kanban board | axe-core with the WCAG 2.0 / 2.1 / 2.2 A + AA rule set against a live API | apps/web/e2e/a11y.spec.ts (fixture e2e/axe-test.ts) |
| Every public page (sign-in, sign-up, reset, booking, poll, flow form, survey, guest invite, signing) | axe (A/AA incl. 2.2) at 1280 and 390 px, no horizontal scroll | e2e/fluent-public.spec.ts |
| 2.4.2 Page Titled | Each route has its own title; a public page uses its own name | e2e/wcag.spec.ts |
| 1.4.10 Reflow | Public pages at 320 CSS px: no horizontal scroll, axe clean | e2e/wcag.spec.ts |
| 2.1.1 Keyboard, 2.4.7 Focus Visible | A public survey completed with the keyboard alone (Tab, arrow keys in a radio group, Enter); every stop must look different when focused | e2e/wcag.spec.ts |
| 2.5.8 Target Size (2.2) | Covered by the 2.2 axe tags | all of the above |
| Markup | jsx-a11y lint (0 errors is the bar) |
npm run lint --workspace @goooy/web |
Run the live sweep with bash scripts/e2e.sh e2e/a11y.spec.ts. The dev
database’s admin@goooy.local may be set to Dutch, which fails every
English-label assertion; switch it to en-US for the run and back after.
Fixed in GEM-05 (2026-09-28)
- 2.4.2 Page Titled (A): the app kept one static title on every route.
RouteTitle+useDocumentTitle(apps/web/src/hooks/useDocumentTitle.ts) now name each module and public page. - 1.4.3 Contrast (AA): the unread badge on the app rail was 75% translucent red, ~3.9:1 behind white text; now opaque, ~5.9:1.
- 4.1.2 Name, Role, Value (A): the Flows list nested the enable switch inside the row’s button (invalid, and unannounced by screen readers); they are siblings now. Delete/remove icon buttons in Admin → Compliance, Groups, Resources, Migrations and the user editor had no accessible name.
- 2.5.8 Target Size (AA, 2.2): the calendar month view’s “+N more” buttons were ~15 px tall; the row is 24 px now.
Not verified yet (known gaps)
Automated tools catch roughly a third of WCAG issues. Before a municipality can claim more than status C (see below), these need a person:
- Screen-reader walkthroughs (NVDA + Firefox, VoiceOver + Safari, TalkBack) of the main tasks: read and send mail, plan a meeting, share a file, chat, join a meeting.
- 1.2.x media: Meet has live, machine-generated captions (see architecture.md); their accuracy has not been reviewed, and recorded meetings have no reviewed captions.
- 1.4.4 Resize text and 1.4.12 Text spacing: not tested by tooling.
- 1.4.13 Content on hover or focus: tooltips/menus not systematically checked.
- 2.2.1 Timing adjustable: session expiry and the MFA challenge (5 minutes) should be reviewed.
- 3.3.x error identification and suggestions beyond the public forms.
- The office editors (DocEditor, SheetEditor, SlidesEditor): canvas-heavy, axe coverage is limited to the chrome.
- The desktop apps (Qt/LibreOffice-based) fall under EN 301 549 chapter 11 (software), not the web criteria, and are not evaluated here.
The statement and its status
The Dutch statement model has five statuses. A (voldoet volledig) and B (voldoet gedeeltelijk) both require an expert evaluation following WCAG-EM, at most three years old, of all 50 criteria, including the areas behind the login. C (eerste maatregelen genomen) needs no evaluation but is only valid for six months, while one is carried out. Source: digitoegankelijk.nl.
So the next step that changes what a municipality can publish is an independent WCAG-EM evaluation of Goooy, commissioned by Goooy and shared with every customer. Until then a municipality publishes status C with that evaluation as its planned measure.
Linking the statement from the product
A government website must link its statement. Set
ACCESSIBILITY_STATEMENT_URL (Helm config.accessibilityStatementUrl,
https:// only) to the municipality’s entry in the register. Then:
- the signed-out public pages (sign-in, forms, booking, polls, signing) show an Accessibility statement link in a footer (static, never covering a focused control), and
- the help panel (
?) shows the same link for signed-in staff.
Without the setting nothing is shown. The value reaches the SPA through the
public GET /api/v1/config.