Internationalization
The dashboard ships English and Italian. Locale policy lives in packages/i18n; the dashboard wires it into @nuxtjs/i18n with strategy: 'no_prefix' (the locale is a user preference, not a URL segment).
Where things live
| Concern | Location |
|---|---|
| Locale definitions | packages/i18n/src (locales, defaultLocale, localeCookieName) |
| Dictionaries | apps/dashboard/i18n/locales/<locale>/, split by scope |
| Translation tooling | packages/i18n/scripts/ |
| Staleness reporting | Lunaria via lunaria.config.ts |
Commands
aube run i18n:report # per-key translation report
aube run i18n:schema # verify every locale matches the English schema
aube run i18n:status # Lunaria staleness report (reads git history)
i18n:status shows which translations went stale relative to the English source; it reads git history, so it needs the dictionaries committed. CI runs the schema check, so a key added to English without its translations fails the build.
Adding or changing messages
- Add the key to the English dictionary in the right scope file.
- Add the same key to every other locale (Italian today) — the schema check enforces parity.
- Use the key from components via the standard
@nuxtjs/i18ncomposables.
Adding a locale
- Declare the locale in
packages/i18n(locales,LocaleCode). - Create
apps/dashboard/i18n/locales/<code>/with a full set of dictionaries. - Run
aube run i18n:schemauntil parity is clean, and commit so Lunaria can track staleness.
Mails
packages/mail owns transactional email: Maizzle-based templates plus a small provider layer. The dashboard uses it for organization invitations and other auth-driven messages.
Deployment
The dashboard is the single deployable artifact: one Nuxt app serving the UI, the control plane, and authentication from one origin.