Naar de inhoud
Documentatie doorbladeren

De documentatie is alleen in het Engels geschreven. De rest van de site is ook in het Nederlands beschikbaar.

Besloten

Languages and accessibility

Supported languages, how translations are structured and tested, and the accessibility bar both apps must meet.

Bijgewerkt: 18 September 2026

Languages

SurfaceLaunchLater
AppsEnglish, DutchGerman (Saymail already ships de, so the tooling exists)
Website marketing and legal pagesEnglish, DutchGerman
Documentation (this site)English onlystays English
Transactional e-mailsEnglish, 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 notificationsrendered 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, Contacts formatting 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

DataRule
Phone numbersStored 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.
DatesDay and month always; year only when shared; displayed with the viewer’s locale, age never computed or shown
AddressesFormatted 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.
NamesDisplayed as entered; sorting uses locale-aware collation on the default name