De documentatie is alleen in het Engels geschreven. De rest van de site is ook in het Nederlands beschikbaar.
Languages and accessibility
Supported languages, how translations are structured and tested, and the accessibility bar both apps must meet.
Bijgewerkt: 18 September 2026
Languages
| Surface | Launch | Later |
|---|---|---|
| Apps | English, Dutch | German (Saymail already ships de, so the tooling exists) |
| Website marketing and legal pages | English, Dutch | German |
| Documentation (this site) | English only | stays English |
| Transactional e-mails | English, Dutch: the Auth e-mails by {{ .Data.language }} in the user’s metadata, the export and deletion e-mails by accounts.preferred_language (falling back to that metadata, then English) (A92) | |
| Push notifications | rendered server-side in the recipient’s devices.locale |
v2 declared English, Spanish and French but the Spanish and French tables were English text; v2 later switched to English + Dutch. v3 ships only languages with complete, reviewed tables.
Structure
Following Saymail, both apps keep translations as typed tables in code (i18n/translations/En.kt, Nl.kt; I18n/TranslationsEn.swift, TranslationsNl.swift) behind a Translator that:
- looks a key up in the active language, falls back to English, and never renders a raw key;
- supports plural forms through the platform’s
PluralRules; - formats dates, phone numbers and addresses with the platform locale APIs (
libphonenumber,DateTimeFormatter,Contactsformatting on iOS).
The language enum, matching rules (exact tag, then base language, then English) and the SUPPORTED list are copied from Saymail’s Language.kt / Language.swift. The in-app language picker lists “Device language” and SUPPORTED; Device language is the default and is stored as accounts.preferred_language = null, a chosen language as its code, so a second device follows it (A81).
Keys are screen.element.variant, for example contacts.section.received_requests, circles.delete.blocked_has_members. Both platforms use the same key set; a script tools/i18n-diff.mjs compares the Kotlin and Swift tables and fails CI on any drift, and KeyParity_ForEveryLanguage_ShouldCoverEveryEnglishKey style tests run on each platform.
Copy rules: sentence case, no exclamation marks, “you/your” (“je/jouw” in Dutch, informal), the product terms from the Glossary used consistently (sharing circle = deelkring, connection = connectie, detail = gegeven, connected service = gekoppelde dienst).
Right-to-left layout is supported structurally (supportsRtl, leading/trailing rather than left/right) although no RTL language ships at launch.
Accessibility
The bar is the same as Saymail’s specification, which both apps already meet:
- Colour is never the only signal. Circle chips carry the circle name; verification state has an icon and a label; sync buckets have text.
- Contrast: WCAG AA for all text, including muted text on cards, verified against the token palette in Visual design.
- Dynamic type: all text scales with the OS setting; lists reflow, rows grow, nothing truncates a value the user must read (a phone number, an address).
- Touch targets ≥ 48 dp / 44 pt, including circle chips, list-row action buttons and the “searchable” toggles.
- Screen readers: every icon-only button labelled (add, edit, delete, favourite, refresh, back); contact rows expose “Name, circle Family, 2 details updated” style descriptions; the circle-dots visualisation exposes the list of circle names as text.
- Reduce motion / transparency honoured: sheet and tab animations dropped, scrims solid.
- Keyboard and focus order on tablets with hardware keyboards: panes are distinct regions, focus ring distinct from selection.
- Acceptance test in each platform’s UI test suite: every row has a non-visual description; largest text size does not truncate a phone number or address; every interactive element ≥ 44/48.
Formatting rules
| Data | Rule |
|---|---|
| Phone numbers | Stored E.164, displayed in national format for the viewer’s region if same country, otherwise international. Parsing and formatting come from libphonenumber-android on Android and a small parser over mobile/design/phone-metadata.json on iOS; docs/vectors/phone-format.json pins both to the same 50 outputs. |
| Dates | Day and month always; year only when shared; displayed with the viewer’s locale, age never computed or shown |
| Addresses | Formatted per the address country’s convention (house number position, postal code order) using mobile/design/address-formats.json, which gives the field order, the label key per field and the one-line display template for NL, BE, DE, GB, US and a default; docs/vectors/address-format.json pins the rendering. |
| Names | Displayed as entered; sorting uses locale-aware collation on the default name |