Skip to content

Identification stage: OR_LIST_FORMATTERS uses hardcoded "default" locale instead of active locale #20632

@CanadianPinguin

Description

@CanadianPinguin

Describe the bug

On the identification stage, when user_fields contains multiple fields (e.g. [email, username]), the field label is generated by joining the translated field names with a disjunction word ("or", "ou", "oder", etc.).

The individual field names are correctly translated via msg() (e.g. "Courriel", "Nom d'utilisateur" in French), but the "or" connector word stays in English regardless of the selected locale.

Root cause

In web/src/flow/stages/identification/IdentificationStage.ts, the OR_LIST_FORMATTERS is defined with a hardcoded "default" locale:

export const OR_LIST_FORMATTERS: Intl.ListFormat = new Intl.ListFormat(
    "default",
    { style: "short", type: "disjunction" }
);

This causes Intl.ListFormat to use the browser's default locale for the disjunction word, not authentik's currently active locale (set via the language switcher or ?locale= URL parameter).

Expected behavior

The Intl.ListFormat should use the currently active authentik locale, so the connector word is properly localized:

  • French: "Courriel ou Nom d'utilisateur"
  • German: "E-Mail oder Anmeldename"
  • English: "Email or Username"

Actual behavior

The connector word "or" remains in English (or whatever the browser's default locale is), while the field names themselves are correctly translated:

  • French: "Courriel or Nom d'utilisateur"
  • German: "E-Mail or Anmeldename"

Suggested fix

Pass the active locale to Intl.ListFormat instead of "default". For example:

const locale = getCurrentLocale(); // or however the active locale is accessed
const OR_LIST_FORMATTERS = new Intl.ListFormat(locale, { style: "short", type: "disjunction" });

Or make it a function that creates the formatter with the current locale at render time, since the locale can change dynamically via the language switcher.

To Reproduce

  1. Set up an identification stage with user_fields: [email, username]
  2. Navigate to the login flow with ?locale=fr (or ?locale=de, or use the language switcher)
  3. Observe the field label shows "Courriel or Nom d'utilisateur" — the "or" is not translated

Version and Deployment

authentik version: 2026.2.0
Deployment: Docker Compose

Related issues

Image Image Image

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions