Skip to content

User locale

Whatever language a user picked, everything they get back comes in that language. The browser tells the server which one it is, the server keeps it in the session, and anything sent out later — a magic-link mail, a background job — reads it from there instead of falling back to a server default.

  • The client sends document.documentElement.lang as an X-Locale header (or Accept-Language) on requests.
  • The server exposes it as an always-present ctx.locale; handlers can answer locale-dependently and derive mail locales from it.

2. Session persistence (SessionUser.locale in the JWT)

Section titled “2. Session persistence (SessionUser.locale in the JWT)”
  • The user’s chosen locale is written into the JWT at login (locale claim) and threaded through login / invite-accept / MFA handlers.
  • SessionUser.locale survives cross-device and background jobs: a job running on the user’s behalf knows their locale.
  • ctx.locale falls back from the live X-Locale signal to SessionUser.locale, keeping a consistent locale even when a request carries no browser locale.

All auth mails (signup, password-reset, email-verification, invite, account-unlock) render in the requester’s locale:

  • appUrl may be a function (locale) => string to build locale-aware landing paths (e.g. /de/...).
  • Mails derive the locale from ctx.locale / SessionUser.locale, never a hard-coded server default.
  • New outbound mails: always derive locale from ctx.locale (fallback SessionUser.locale), never hard-code a server default.
  • Use appUrl as (locale) => string when the landing path is locale-sensitive.