diff --git a/README.md b/README.md
index 60f8393a7..97a4a450c 100644
--- a/README.md
+++ b/README.md
@@ -17,6 +17,7 @@
[](https://discord.gg/Ee5hd458Uz)
[](https://opencollective.com/booklore)
+[](https://hosted.weblate.org/engage/booklore/)
---
@@ -391,6 +392,22 @@ Join community!
+---
+
+
+
+## 🌍 **Translations**
+
+Help translate BookLore into your language!
+
+
+
+
+
+Read more about translations [here](https://hosted.weblate.org/engage/booklore/).
+
+
+
---
diff --git a/booklore-ui/src/i18n/de/auth.json b/booklore-ui/src/i18n/de/auth.json
index 0967ef424..845807612 100644
--- a/booklore-ui/src/i18n/de/auth.json
+++ b/booklore-ui/src/i18n/de/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Willkommen zurück",
+ "subtitle": "Melden Sie sich an, um fortzufahren",
+ "usernameLabel": "Benutzername",
+ "usernamePlaceholder": "Benutzername eingeben",
+ "passwordLabel": "Passwort",
+ "passwordPlaceholder": "Passwort eingeben",
+ "signIn": "Anmelden",
+ "orContinueWith": "oder weiter mit",
+ "redirectingTo": "Weiterleitung zu {{provider}}...",
+ "oidcTrouble": "Probleme mit {{provider}}? Lokale Anmeldung verwenden",
+ "reEnableOidc": "{{provider}}-Anmeldung wieder aktivieren",
+ "connectionError": "Verbindung zum Server nicht möglich. Bitte überprüfen Sie Ihre Verbindung und versuchen Sie es erneut.",
+ "unexpectedError": "Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.",
+ "oidcInitError": "OIDC-Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut oder verwenden Sie die lokale Anmeldung.",
+ "oidcWarningTitle": "OIDC-Authentifizierungsprobleme",
+ "retryOidc": "OIDC erneut versuchen",
+ "useLocalLogin": "Lokale Anmeldung verwenden",
+ "oidcAutoDisabled": "Die Authentifizierung über {{provider}} wurde nach {{count}} aufeinanderfolgenden Fehlern (einschließlich Zeitüberschreitungen) automatisch deaktiviert. Sie können es erneut versuchen oder mit der lokalen Anmeldung fortfahren.",
+ "oidcManuallyDisabled": "Die Authentifizierung über {{provider}} wurde manuell deaktiviert. Sie können sie wieder aktivieren oder mit der lokalen Anmeldung fortfahren.",
+ "oidcErrors": "Die Authentifizierung über {{provider}} hat {{count}} Fehler festgestellt, möglicherweise aufgrund von Zeitüberschreitungen oder Serverproblemen."
+ }
+}
diff --git a/booklore-ui/src/i18n/fr/auth.json b/booklore-ui/src/i18n/fr/auth.json
index 0967ef424..7905be7ee 100644
--- a/booklore-ui/src/i18n/fr/auth.json
+++ b/booklore-ui/src/i18n/fr/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Bon retour",
+ "subtitle": "Connectez-vous pour continuer",
+ "usernameLabel": "Nom d'utilisateur",
+ "usernamePlaceholder": "Entrez votre nom d'utilisateur",
+ "passwordLabel": "Mot de passe",
+ "passwordPlaceholder": "Entrez votre mot de passe",
+ "signIn": "Se connecter",
+ "orContinueWith": "ou continuer avec",
+ "redirectingTo": "Redirection vers {{provider}}...",
+ "oidcTrouble": "Des problèmes avec {{provider}} ? Utilisez la connexion locale",
+ "reEnableOidc": "Réactiver la connexion {{provider}}",
+ "connectionError": "Impossible de se connecter au serveur. Veuillez vérifier votre connexion et réessayer.",
+ "unexpectedError": "Une erreur inattendue s'est produite. Veuillez réessayer.",
+ "oidcInitError": "Échec de la connexion OIDC. Veuillez réessayer ou utilisez la connexion locale.",
+ "oidcWarningTitle": "Problèmes d'authentification OIDC",
+ "retryOidc": "Réessayer OIDC",
+ "useLocalLogin": "Utiliser la connexion locale",
+ "oidcAutoDisabled": "L'authentification {{provider}} a été automatiquement désactivée après {{count}} échecs consécutifs (y compris les délais d'attente). Vous pouvez réessayer ou continuer avec la connexion locale.",
+ "oidcManuallyDisabled": "L'authentification {{provider}} a été désactivée manuellement. Vous pouvez la réactiver ou continuer avec la connexion locale.",
+ "oidcErrors": "L'authentification {{provider}} a rencontré {{count}} erreur(s), possiblement en raison de délais d'attente ou de problèmes serveur."
+ }
+}
diff --git a/booklore-ui/src/i18n/it/auth.json b/booklore-ui/src/i18n/it/auth.json
index 0967ef424..5116fa3b6 100644
--- a/booklore-ui/src/i18n/it/auth.json
+++ b/booklore-ui/src/i18n/it/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Bentornato",
+ "subtitle": "Accedi per continuare il tuo viaggio",
+ "usernameLabel": "Nome utente",
+ "usernamePlaceholder": "Inserisci il tuo nome utente",
+ "passwordLabel": "Password",
+ "passwordPlaceholder": "Inserisci la tua password",
+ "signIn": "Accedi",
+ "orContinueWith": "o continua con",
+ "redirectingTo": "Reindirizzamento a {{provider}}...",
+ "oidcTrouble": "Problemi con {{provider}}? Usa l'accesso locale",
+ "reEnableOidc": "Riattiva l'accesso con {{provider}}",
+ "connectionError": "Impossibile connettersi al server. Controlla la connessione e riprova.",
+ "unexpectedError": "Si è verificato un errore imprevisto. Riprova.",
+ "oidcInitError": "Impossibile avviare l'accesso OIDC. Riprova o usa l'accesso locale.",
+ "oidcWarningTitle": "Problemi di autenticazione OIDC",
+ "retryOidc": "Riprova OIDC",
+ "useLocalLogin": "Usa accesso locale",
+ "oidcAutoDisabled": "L'autenticazione {{provider}} è stata disattivata automaticamente dopo {{count}} errori consecutivi (inclusi i timeout). Puoi riprovare o continuare con l'accesso locale.",
+ "oidcManuallyDisabled": "L'autenticazione {{provider}} è stata disattivata manualmente. Puoi riattivarla o continuare con l'accesso locale.",
+ "oidcErrors": "L'autenticazione {{provider}} ha riscontrato {{count}} errore/i, probabilmente a causa di timeout o problemi del server."
+ }
+}
diff --git a/booklore-ui/src/i18n/nl/auth.json b/booklore-ui/src/i18n/nl/auth.json
index 0967ef424..abb4629f5 100644
--- a/booklore-ui/src/i18n/nl/auth.json
+++ b/booklore-ui/src/i18n/nl/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Welkom terug",
+ "subtitle": "Log in om verder te gaan",
+ "usernameLabel": "Gebruikersnaam",
+ "usernamePlaceholder": "Voer je gebruikersnaam in",
+ "passwordLabel": "Wachtwoord",
+ "passwordPlaceholder": "Voer je wachtwoord in",
+ "signIn": "Inloggen",
+ "orContinueWith": "of ga verder met",
+ "redirectingTo": "Doorverwijzen naar {{provider}}...",
+ "oidcTrouble": "Problemen met {{provider}}? Gebruik lokale login",
+ "reEnableOidc": "{{provider}}-login opnieuw inschakelen",
+ "connectionError": "Kan geen verbinding maken met de server. Controleer je verbinding en probeer het opnieuw.",
+ "unexpectedError": "Er is een onverwachte fout opgetreden. Probeer het opnieuw.",
+ "oidcInitError": "OIDC-login mislukt. Probeer het opnieuw of gebruik de lokale login.",
+ "oidcWarningTitle": "OIDC-authenticatieproblemen",
+ "retryOidc": "OIDC opnieuw proberen",
+ "useLocalLogin": "Lokale login gebruiken",
+ "oidcAutoDisabled": "{{provider}}-authenticatie is automatisch uitgeschakeld na {{count}} opeenvolgende fouten (inclusief time-outs). Je kunt het opnieuw proberen of doorgaan met de lokale login.",
+ "oidcManuallyDisabled": "{{provider}}-authenticatie is handmatig uitgeschakeld. Je kunt het opnieuw inschakelen of doorgaan met de lokale login.",
+ "oidcErrors": "{{provider}}-authenticatie heeft {{count}} fout(en) ondervonden, mogelijk door time-outs of serverproblemen."
+ }
+}
diff --git a/booklore-ui/src/i18n/pl/auth.json b/booklore-ui/src/i18n/pl/auth.json
index 0967ef424..264a3301d 100644
--- a/booklore-ui/src/i18n/pl/auth.json
+++ b/booklore-ui/src/i18n/pl/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Witaj ponownie",
+ "subtitle": "Zaloguj się, aby kontynuować",
+ "usernameLabel": "Nazwa użytkownika",
+ "usernamePlaceholder": "Wprowadź nazwę użytkownika",
+ "passwordLabel": "Hasło",
+ "passwordPlaceholder": "Wprowadź hasło",
+ "signIn": "Zaloguj się",
+ "orContinueWith": "lub kontynuuj przez",
+ "redirectingTo": "Przekierowanie do {{provider}}...",
+ "oidcTrouble": "Problemy z {{provider}}? Użyj logowania lokalnego",
+ "reEnableOidc": "Ponownie włącz logowanie przez {{provider}}",
+ "connectionError": "Nie można połączyć się z serwerem. Sprawdź połączenie i spróbuj ponownie.",
+ "unexpectedError": "Wystąpił nieoczekiwany błąd. Spróbuj ponownie.",
+ "oidcInitError": "Nie udało się uruchomić logowania OIDC. Spróbuj ponownie lub użyj logowania lokalnego.",
+ "oidcWarningTitle": "Problemy z uwierzytelnianiem OIDC",
+ "retryOidc": "Ponów OIDC",
+ "useLocalLogin": "Użyj logowania lokalnego",
+ "oidcAutoDisabled": "Uwierzytelnianie {{provider}} zostało automatycznie wyłączone po {{count}} kolejnych błędach (w tym przekroczeniach czasu). Możesz spróbować ponownie lub kontynuować z logowaniem lokalnym.",
+ "oidcManuallyDisabled": "Uwierzytelnianie {{provider}} zostało ręcznie wyłączone. Możesz je ponownie włączyć lub kontynuować z logowaniem lokalnym.",
+ "oidcErrors": "Uwierzytelnianie {{provider}} napotkało {{count}} błąd(ów), prawdopodobnie z powodu przekroczeń czasu lub problemów z serwerem."
+ }
+}
diff --git a/booklore-ui/src/i18n/pt/auth.json b/booklore-ui/src/i18n/pt/auth.json
index 0967ef424..c60d8c583 100644
--- a/booklore-ui/src/i18n/pt/auth.json
+++ b/booklore-ui/src/i18n/pt/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "Bem-vindo de volta",
+ "subtitle": "Inicie sessão para continuar",
+ "usernameLabel": "Nome de utilizador",
+ "usernamePlaceholder": "Introduza o seu nome de utilizador",
+ "passwordLabel": "Palavra-passe",
+ "passwordPlaceholder": "Introduza a sua palavra-passe",
+ "signIn": "Iniciar sessão",
+ "orContinueWith": "ou continuar com",
+ "redirectingTo": "A redirecionar para {{provider}}...",
+ "oidcTrouble": "Problemas com {{provider}}? Use o início de sessão local",
+ "reEnableOidc": "Reativar início de sessão com {{provider}}",
+ "connectionError": "Não é possível ligar ao servidor. Verifique a sua ligação e tente novamente.",
+ "unexpectedError": "Ocorreu um erro inesperado. Tente novamente.",
+ "oidcInitError": "Falha ao iniciar o início de sessão OIDC. Tente novamente ou use o início de sessão local.",
+ "oidcWarningTitle": "Problemas de autenticação OIDC",
+ "retryOidc": "Tentar OIDC novamente",
+ "useLocalLogin": "Usar início de sessão local",
+ "oidcAutoDisabled": "A autenticação {{provider}} foi automaticamente desativada após {{count}} falhas consecutivas (incluindo tempos limite). Pode tentar novamente ou continuar com o início de sessão local.",
+ "oidcManuallyDisabled": "A autenticação {{provider}} foi desativada manualmente. Pode reativá-la ou continuar com o início de sessão local.",
+ "oidcErrors": "A autenticação {{provider}} encontrou {{count}} erro(s), possivelmente devido a tempos limite ou problemas no servidor."
+ }
+}
diff --git a/booklore-ui/src/i18n/ru/auth.json b/booklore-ui/src/i18n/ru/auth.json
index 0967ef424..a13c58c98 100644
--- a/booklore-ui/src/i18n/ru/auth.json
+++ b/booklore-ui/src/i18n/ru/auth.json
@@ -1 +1,24 @@
-{}
+{
+ "login": {
+ "title": "С возвращением",
+ "subtitle": "Войдите, чтобы продолжить",
+ "usernameLabel": "Имя пользователя",
+ "usernamePlaceholder": "Введите имя пользователя",
+ "passwordLabel": "Пароль",
+ "passwordPlaceholder": "Введите пароль",
+ "signIn": "Войти",
+ "orContinueWith": "или продолжить через",
+ "redirectingTo": "Перенаправление на {{provider}}...",
+ "oidcTrouble": "Проблемы с {{provider}}? Используйте локальный вход",
+ "reEnableOidc": "Повторно включить вход через {{provider}}",
+ "connectionError": "Не удаётся подключиться к серверу. Проверьте подключение и попробуйте снова.",
+ "unexpectedError": "Произошла непредвиденная ошибка. Попробуйте снова.",
+ "oidcInitError": "Не удалось инициировать вход через OIDC. Попробуйте снова или используйте локальный вход.",
+ "oidcWarningTitle": "Проблемы аутентификации OIDC",
+ "retryOidc": "Повторить OIDC",
+ "useLocalLogin": "Использовать локальный вход",
+ "oidcAutoDisabled": "Аутентификация {{provider}} была автоматически отключена после {{count}} последовательных ошибок (включая тайм-ауты). Вы можете повторить попытку или продолжить с локальным входом.",
+ "oidcManuallyDisabled": "Аутентификация {{provider}} была отключена вручную. Вы можете включить её снова или продолжить с локальным входом.",
+ "oidcErrors": "Аутентификация {{provider}} обнаружила {{count}} ошибку(ок), возможно, из-за тайм-аутов или проблем с сервером."
+ }
+}
diff --git a/scripts/weblate-setup.sh b/scripts/weblate-setup.sh
new file mode 100755
index 000000000..2c3792a11
--- /dev/null
+++ b/scripts/weblate-setup.sh
@@ -0,0 +1,183 @@
+#!/usr/bin/env bash
+#
+# Weblate Setup Script for BookLore
+#
+# Creates the Weblate project and all 25 translation components via the API.
+# Run once after creating your Hosted Weblate account.
+#
+# Prerequisites:
+# 1. Get your API token from https://hosted.weblate.org/accounts/profile/#api
+# 2. Ensure your GitHub repo (booklore-app/booklore) is public (required for Libre plan)
+#
+# Usage:
+# WEBLATE_TOKEN=your-api-token ./scripts/weblate-setup.sh
+#
+
+set -euo pipefail
+
+# ─── Configuration ────────────────────────────────────────────────────────────
+WEBLATE_URL="${WEBLATE_URL:-https://hosted.weblate.org}"
+API="${WEBLATE_URL}/api"
+TOKEN="${WEBLATE_TOKEN:?Set WEBLATE_TOKEN to your Weblate API token}"
+
+PROJECT_NAME="BookLore"
+PROJECT_SLUG="booklore"
+PROJECT_WEB="https://github.com/booklore-app/booklore"
+
+REPO_URL="https://github.com/booklore-app/booklore.git"
+REPO_BRANCH="develop"
+FILE_BASE="booklore-ui/src/i18n"
+
+SOURCE_LANG="en"
+
+# All languages the project supports
+LANGUAGES="en es de fr it nl pl pt ru"
+
+# All 25 translation domain files (without .json extension)
+COMPONENTS=(
+ common
+ auth
+ nav
+ dashboard
+ settings
+ settings-email
+ settings-reader
+ settings-view
+ settings-metadata
+ settings-library-metadata
+ settings-application
+ settings-users
+ settings-naming
+ settings-opds
+ settings-tasks
+ settings-auth
+ settings-device
+ settings-profile
+ app
+ shared
+ layout
+ library-creator
+ bookdrop
+ metadata
+)
+
+# ─── Helpers ──────────────────────────────────────────────────────────────────
+auth_header="Authorization: Token ${TOKEN}"
+content_type="Content-Type: application/json"
+
+api_post() {
+ local endpoint="$1"
+ local data="$2"
+ local response
+ response=$(curl -s -w "\n%{http_code}" -X POST "${API}${endpoint}" \
+ -H "${auth_header}" \
+ -H "${content_type}" \
+ -d "${data}")
+ local http_code
+ http_code=$(echo "$response" | tail -1)
+ local body
+ body=$(echo "$response" | sed '$d')
+
+ if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
+ echo " OK (${http_code})"
+ return 0
+ elif [[ "$http_code" == "400" ]] && echo "$body" | grep -q "already exists"; then
+ echo " Already exists, skipping"
+ return 0
+ else
+ echo " FAILED (${http_code}): ${body}"
+ return 1
+ fi
+}
+
+# Pretty name from slug: settings-email -> Settings Email
+pretty_name() {
+ echo "$1" | sed 's/-/ /g' | awk '{for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2))}1'
+}
+
+# ─── Step 1: Create Project ──────────────────────────────────────────────────
+echo "=== Creating project: ${PROJECT_NAME} ==="
+api_post "/projects/" "$(cat <