Skip to content

Internationalization (i18n)

import { Aside, Steps } from ‘@astrojs/starlight/components’;

Kotauth externalizes all user-facing strings in auth pages and the self-service portal through a translation system. The default language is English, and additional languages can be added by mounting JSON translation bundles — no recompilation required.

All UI strings flow through a TranslationPort interface in the domain layer. The default implementation (EnglishStrings) provides the full set of English strings. When a translation bundle is loaded for a language, it overrides the English defaults for that locale.

Language resolution follows the Accept-Language header sent by the browser, with quality-factor ranking. If no matching bundle exists, Kotauth falls back to English.

Each workspace can set a default locale in the admin console under Settings → General. This locale is used when the browser does not send an Accept-Language header or when the requested locale has no matching bundle.

  1. Create a JSON file named with the locale code (e.g. es.json, fr.json, de.json)
  2. Add key-value pairs matching the English string keys
  3. Mount the file into the container at the path specified by KAUTH_I18N_BUNDLE_DIR
  4. Restart Kotauth — the new language is available immediately

Translation bundles are flat JSON objects with string keys and string values:

{
"login.title": "Iniciar sesión",
"login.email.label": "Correo electrónico",
"login.email.placeholder": "tu@correo.com",
"login.password.label": "Contraseña",
"login.submit": "Iniciar sesión",
"login.magic_link": "Iniciar sesión con enlace mágico",
"login.forgot_password": "¿Olvidaste tu contraseña?",
"login.register": "Crear una cuenta",
"mfa.title": "Verificación en dos pasos",
"mfa.code.label": "Código de verificación",
"mfa.submit": "Verificar",
"portal.sessions.title": "Sesiones activas",
"portal.sessions.revoke": "Revocar sesión"
}

Partial bundles are supported — any key not present in the bundle falls back to the English default. This lets you translate incrementally without needing to cover all strings at once.

Mount your translation bundles directory and set the environment variable:

services:
kauth:
image: ghcr.io/inumansoul/kotauth:latest
environment:
KAUTH_I18N_BUNDLE_DIR: /i18n
volumes:
- ./i18n:/i18n:ro

Directory structure:

i18n/
├── es.json # Spanish
├── fr.json # French
└── pt.json # Portuguese
VariableDefaultDescription
KAUTH_I18N_BUNDLE_DIRPath to directory containing JSON translation bundles. When not set, only English is available.

Each workspace can configure a default locale in the admin console:

  1. Navigate to Settings → General
  2. Set the Default locale field to a locale code (e.g. es, fr, de)
  3. Save

When a user’s browser does not specify a language preference, the workspace default locale is used instead of English.

As of v1.10.0, zero hardcoded English strings remain in auth pages or the self-service portal. Every user-facing string is routed through the translation system, including:

  • Login, registration, and password reset pages
  • MFA enrollment and challenge screens
  • Magic-link request and confirmation pages
  • Self-service portal (profile, sessions, MFA management, social accounts)
  • Email templates (subject lines and body text)
  • Validation error messages
  • Toast notifications and confirmation dialogs