Per-account UI language preference (cross-device persistence) #40

Open
opened 2026-06-05 12:25:50 +00:00 by logaritmisk · 0 comments
Owner

Context

Follow-up from the "instance locale + single-language content authoring" milestone
(docs/superpowers/specs/2026-06-05-instance-locale-and-content-authoring-design.md).

That milestone sets the instance default UI language via the DEFAULT_LANGUAGE env var,
surfaced through GET /api/config, and a fresh browser defaults to it. A user can already
switch language for their browser via the existing LangSwitch (persisted in
localStorage[LOCALE_KEY]). What's missing is a per-account preference that follows the
user across devices/browsers — e.g. a curator who prefers English even on a Swedish
instance shouldn't have to re-switch on every machine.

Ask

  • Add a nullable language column to app_user (null = "use the instance default").
  • Expose/accept it on the user surface: include it in UserView / GET /api/admin/me, and
    add a way to set it (a small PATCH /api/admin/me or a preference endpoint; decide).
  • Frontend: on login / me load, initialize i18n from the account language when set,
    taking precedence over the instance default (and reconcile with the existing
    localStorage override — decide the precedence: account preference as the source of
    truth, with localStorage as a fast local cache).
  • Audit the change if it touches security-relevant account state (likely not — UI
    preference; confirm against the audit policy).

Precedence (to settle during design)

Proposed order, highest first: explicit in-session LangSwitch → account language
instance DEFAULT_LANGUAGE → built-in fallback. (i.e. account preference seeds the initial
language; an in-session switch still wins until reload, and may update the account
preference.)

Acceptance

  • A logged-in user's UI language follows their account across browsers/devices.
  • Null account language falls back to the instance default; nothing regresses for users who
    never set a preference.

Notes

  • Deliberately deferred from the instance-locale milestone (lower priority; per-browser
    persistence already covers the single-machine case).
  • Low-risk, additive: a nullable column + a me-surface field + SPA init wiring.

Filed per the instance-locale brainstorm (2026-06-05).

## Context Follow-up from the "instance locale + single-language content authoring" milestone (`docs/superpowers/specs/2026-06-05-instance-locale-and-content-authoring-design.md`). That milestone sets the **instance default** UI language via the `DEFAULT_LANGUAGE` env var, surfaced through `GET /api/config`, and a fresh browser defaults to it. A user can already switch language for their **browser** via the existing `LangSwitch` (persisted in `localStorage[LOCALE_KEY]`). What's missing is a **per-account** preference that follows the user **across devices/browsers** — e.g. a curator who prefers English even on a Swedish instance shouldn't have to re-switch on every machine. ## Ask - Add a nullable `language` column to `app_user` (null = "use the instance default"). - Expose/accept it on the user surface: include it in `UserView` / `GET /api/admin/me`, and add a way to set it (a small `PATCH /api/admin/me` or a preference endpoint; decide). - Frontend: on login / `me` load, initialize i18n from the account `language` when set, taking precedence over the instance default (and reconcile with the existing `localStorage` override — decide the precedence: account preference as the source of truth, with localStorage as a fast local cache). - Audit the change if it touches security-relevant account state (likely not — UI preference; confirm against the audit policy). ## Precedence (to settle during design) Proposed order, highest first: explicit in-session `LangSwitch` → account `language` → instance `DEFAULT_LANGUAGE` → built-in fallback. (i.e. account preference seeds the initial language; an in-session switch still wins until reload, and may update the account preference.) ## Acceptance - A logged-in user's UI language follows their account across browsers/devices. - Null account language falls back to the instance default; nothing regresses for users who never set a preference. ## Notes - Deliberately deferred from the instance-locale milestone (lower priority; per-browser persistence already covers the single-machine case). - Low-risk, additive: a nullable column + a `me`-surface field + SPA init wiring. _Filed per the instance-locale brainstorm (2026-06-05)._
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logaritmisk/biggus-dickus#40