Multilingual support
Multilingual support
FamilyHub is multilingual end-to-end. The UI, the AI assistant, the speech-to-text model, and this marketing site all follow the same two-letter language preference: NL (Dutch) or EN (English) today.
How it works
Language lives on the family, not the user. When a Family Admin picks a language under Admin > Settings, the setting propagates everywhere:
- Web UI — the React PWA switches its translation bundle on the fly.
- AI assistant — Claude/OpenAI prompts and responses use the family language. A Dutch command like "voeg melk toe" and an English command like "add milk" both route to
AddShoppingItems. - Speech-to-text — FamilyHub passes the family's two-letter language code (
nl/en) to Whisper on every transcription request. The actual model is whatever you configured (managed tier defaults to OpenAI'swhisper-1; self-hosted setups withfaster-whispertypically picklarge-v3for best Dutch quality), and the language flag just tells that model which language to expect. - Emails — trial, invitation, and subscription emails are sent in the family language.
- Docs / store — this site has a Dutch and English version of every page and blog post.
Supported today
| Code | Language |
|---|---|
NL | Dutch (Nederlands) — the original language, fully tuned |
EN | English |
Backed by the Language enum in the domain model (familyhub-api/src/main/kotlin/business/yv/familyhub/domain/family/Language.kt) and persisted via Flyway migration V27.
Changing the family language
- Sign in as a Family Admin.
- Open Admin > Settings.
- Pick the language from the dropdown and save.
- Every connected device updates instantly — no reload needed.
The choice also retro-actively changes the language of AI responses going forward. Existing data (shopping list names, task titles, event titles) is left untouched — FamilyHub doesn't translate your content for you.
User-level override (store / marketing site)
On this marketing site (familyhub-store) the language is a browser-level choice, independent of any family. Switch it in the top-right corner — the pick is remembered per browser.
Adding another language
The plumbing is in three places:
- Backend — add a value to the
Languageenum, extendWhisperSttAdapter.familyLanguageCode()to map it to the right two-letter code, and make sure the AI prompt templates cover the new language. - Frontend — add a translation bundle under
familyhub-web/src/i18n/and wire it into the language picker. - Store — add a translation object under
familyhub-store/src/i18n/translations/alongsideen.ts/nl.ts, and create<slug>.<lang>.mdxsiblings for each doc and blog post.
Contributions welcome — open a merge request on GitLab.
Dutch vs English — parity note
FamilyHub started as a Dutch-first product (that's how the creator's family uses it), so Dutch tends to land first. Category names and a handful of domain constants still carry their Dutch form in the database for clarity (ShoppingCategory.ZUIVEL, GROENTE_FRUIT, …), but these are displayed through the translation layer — English users see "Dairy", "Produce", etc.