Repository: amir20/dozzle (language: go)

Issue:
[8.1.0] Label.Container
![image](https://github.com/user-attachments/assets/b4d8ac61-b671-49a8-9857-f67033bfd611)

somehow something is displayed wrong in the container


Discussion / hints:
And this one 
![image](https://github.com/user-attachments/assets/dd5df21e-12a4-4799-85df-83c5888bb37b)

next one `button.canel`

![image](https://github.com/user-attachments/assets/534df5db-580c-4c2c-91a2-f5fa6b2202f0)

I think I know the issue. I load the locales asynchronously. Seems like fallback is broken. 

Fix patch:
diff --git a/assets/main.ts b/assets/main.ts
index bd1715afe069..aa8e458f3d8f 100644
--- a/assets/main.ts
+++ b/assets/main.ts
@@ -3,8 +3,8 @@ import { createApp, App as VueApp } from "vue";
 import App from "./App.vue";
 
 const app = createApp(App);
-Object.values(import.meta.glob<{ install: (app: VueApp) => void }>("./modules/*.ts", { eager: true })).forEach(
-  (i) => i.install?.(app),
+Object.values(import.meta.glob<{ install: (app: VueApp) => void }>("./modules/*.ts", { eager: true })).forEach((i) =>
+  i.install?.(app),
 );
 
 app.mount("#app");
diff --git a/assets/modules/i18n.ts b/assets/modules/i18n.ts
index a3fc733a30f5..8f8bfaa849d6 100644
--- a/assets/modules/i18n.ts
+++ b/assets/modules/i18n.ts
@@ -17,10 +17,19 @@ function setI18nLanguage(lang: Locale) {
   return lang;
 }
 
+const i18n = createI18n({
+  legacy: false,
+  locale: "",
+  fallbackLocale: "en",
+  messages: {},
+});
+
 const loadedLanguages: string[] = [];
-async function loadLanguage(lang: string): Promise<Locale> {
-  if (i18n.global.locale.value === lang) return setI18nLanguage(lang);
-  if (loadedLanguages.includes(lang)) return setI18nLanguage(lang);
+async function loadLanguage(lang: string, setLang = true): Promise<Locale> {
+  if (setLang) {
+    if (i18n.global.locale.value === lang) return setI18nLanguage(lang);
+    if (loadedLanguages.includes(lang)) return setI18nLanguage(lang);
+  }
 
   const messages = await localesMap[lang]();
   i18n.global.setLocaleMessage(lang, messages.default);
@@ -28,19 +37,20 @@ async function loadLanguage(lang: string): Promise<Locale> {
   return setI18nLanguage(lang);
 }
 
-const i18n = createI18n({
-  legacy: false,
-  locale: "",
-  messages: {},
-});
+await loadLanguage("en", false); // load default language
 
-watchEffect(() => {
-  loadLanguage(
+const userLocale = computed(
+  () =>
     locale.value ||
-      [navigator.language, navigator.language.slice(0, 2)].find((l) => availableLocales.includes(l)) ||
-      "en",
-  );
-});
+    [navigator.language, navigator.language.slice(0, 2)].find((l) => availableLocales.includes(l)) ||
+    "en",
+);
+
+if (userLocale.value !== "en") {
+  await loadLanguage(userLocale.value);
+}
+
+watchEffect(() => loadLanguage(userLocale.value));
 
 export const install = (app: App) => app.use(i18n);
 export default i18n;
diff --git a/locales/da.yml b/locales/da.yml
index 4f3f6116e164..972226987ad9 100644
--- a/locales/da.yml
+++ b/locales/da.yml
@@ -13,6 +13,7 @@ label:
   running-containers: Kørende Containere
   all-containers: Alle Containere
   host: Vært
+  hosts: Værter
   password: Kodeord
   username: Brugernavn
   container-name: Container Navn
diff --git a/locales/de.yml b/locales/de.yml
index 5511398fc241..5ea330ba0a62 100644
--- a/locales/de.yml
+++ b/locales/de.yml
@@ -6,6 +6,7 @@ toolbar:
   show-all: Zeige alle Streams
 label:
   containers: Container
+  container: Keine Container | 1 Container | {count} Container
   running-containers: Laufende Container
   all-containers: Alle Container
   total-containers: Gesamte Container
@@ -15,6 +16,7 @@ label:
   dozzle-version: Dozzle Version
   all: Alle
   host: Host
+  hosts: Hosts
   password: Passwort
   username: Benutzername
   container-name: Container Name
@@ -26,6 +28,8 @@ label:
 tooltip:
   search: Suche Container (⌘ + k, ⌃k)
   pin-column: Als Spalte anheften
+  merge-services: Services zusammenführen
+  merge-containers: Container zusammenführen
 error:
   page-not-found: Diese Seite existiert nicht.
   invalid-auth: Benutzername und Passwort sind ungültig.
@@ -69,6 +73,7 @@ settings:
   small-scrollbars: Verwende kleinere Scrollbars
   show-timesamps: Zeige Zeitstempel
   soft-wrap: Zeilenumbruch
+  datetime-format: Datums- und Zeitformat
   12-24-format: >-
     Standardmäßig verwendet Dozzle die Spracheinstellungen des Browsers, um die
     Zeit anzuzeigen. Du kannst die Zeit auf 12 oder 24 Stunden umstellen.
diff --git a/locales/es.yml b/locales/es.yml
index bf69f7f21495..4eedb2bdbe4b 100644
--- a/locales/es.yml
+++ b/locales/es.yml
@@ -9,6 +9,7 @@ toolbar:
   restart: Reiniciar
 label:
   containers: Contenedores
+  container: No contenedores | 1 contenedor | {count} contenedores
   running-containers: Contenedores en ejecución
   all-containers: Todos los contenedores
   total-containers: Contenedores Totales
@@ -18,6 +19,7 @@ label:
   dozzle-version: Versión de Dozzle
   all: Todo
   host: Host
+  hosts: Hosts
   password: Contraseña
   username: Nombre de usuario
   container-name: Nombre del contenedor
diff --git a/locales/fr.yml b/locales/fr.yml
index ce8fd84506d1..b7858d7dd091 100644
--- a/locales/fr.yml
+++ b/locales/fr.yml
@@ -13,6 +13,7 @@ label:
   running-containers: Conteneurs en execution
   all-containers: Tous les conteneurs
   host: Hôte
+  hosts: Hôtes
   password: Mot de passe
   username: Nom d'utilisateur
   container-name: Nom du conteneur
diff --git a/locales/it.yml b/locales/it.yml
index daff542e2d19..c301897f8f7f 100644
--- a/locales/it.yml
+++ b/locales/it.yml
@@ -18,6 +18,7 @@ label:
   dozzle-version: Versione Dozzle
   all: Tutto
   host: Host
+  hosts: Hosts
   password: Password
   username: Username
   container-name: Nome Container
diff --git a/locales/pl.yml b/locales/pl.yml
index 292bf2c5d15f..0eacca23ce76 100644
--- a/locales/pl.yml
+++ b/locales/pl.yml
@@ -13,6 +13,7 @@ label:
   running-containers: Działające kontenery
   all-containers: Wszystkie kontenery
   host: Host
+  hosts: Hosty
   password: Hasło
   username: Nazwa użytkownika
   container-name: Nazwa kontenera
@@ -29,17 +30,17 @@ tooltip:
 error:
   page-not-found: Ta strona nie istnieje
   invalid-auth: Nazwa użytkownika lub hasło są niepoprawne
-  logs-skipped: Pominiętych wpisów {total} 
+  logs-skipped: Pominiętych wpisów {total}
   container-not-found: Kontener nie został znaleziony
   events-stream:
     title: Niespodziewany błąd
     message: >-
       Dozzle nie był wstanie połączyć się z API. Sprawdź ustawienia sieciowe.
-      Jeżeli korzysasz z reverse proxy, upewnij się że jest poprawnie skonfigurowane. 
+      Jeżeli korzysasz z reverse proxy, upewnij się że jest poprawnie skonfigurowane.
   events-timeout:
     title: Coś jest nie tak
     message: >-
-      Przekroczono limit czasu w trakcie połączenia do API. Sprawdź ustawienia sieciowe.  
+      Przekroczono limit czasu w trakcie połączenia do API. Sprawdź ustawienia sieciowe.
 alert:
   redirected:
     title: Przekierowywanie do nowego kontenera
@@ -47,7 +48,7 @@ alert:
   similar-container-found:
     title: Podobny kontener został znaleziony
     message: >-
-      Dozzle znalazł podobny kontener {containerId} który działa na tym samym 
+      Dozzle znalazł podobny kontener {containerId} który działa na tym samym
       hoście i przekieruje Cię na niego automatycznie jeżeli nie klikniesz 'Anuluj'
 title:
   page-not-found: Strona nie została znaleziona
@@ -55,7 +56,7 @@ title:
   dashboard: 1 kontener | {count} kontenerów
   settings: Ustawienia
 button:
-  logout: Wyloguj się 
+  logout: Wyloguj się
   login: Zaloguj się
   settings: Ustawienia
 placeholder:
diff --git a/locales/pr.yml b/locales/pr.yml
index 5de035c60119..1643f7cdb018 100644
--- a/locales/pr.yml
+++ b/locales/pr.yml
@@ -15,6 +15,7 @@ label:
   dozzle-version: Versão Dozzle
   all: Tudo
   host: Anfitrião
+  hosts: Anfitriões
   password: Senha
   username: Nome de usuário
   container-name: Nome do contentor
@@ -71,6 +72,7 @@ settings:
   font-size: Tamanho de letra a utilizar para os registos
   color-scheme: Esquema de cores
   options: Opções
+  datetime-format: Formato de data e hora
   show-stopped-containers: Mostrar contentores parados
   about: Acerca de
   search: Habilitar a pesquisa com Dozzle usando
diff --git a/locales/ru.yml b/locales/ru.yml
index a4e19ac9fb74..24ba47e66467 100644
--- a/locales/ru.yml
+++ b/locales/ru.yml
@@ -15,6 +15,7 @@ label:
   dozzle-version: Версия Dozzle
   all: Все
   host: Хост
+  hosts: Хосты
   password: Пароль
   username: Имя пользователя
   container-name: Имя контейнера
@@ -71,6 +72,7 @@ settings:
   color-scheme: Цветовая схема
   options: Опции
   show-stopped-containers: Показывать остановленные контейнеры
+  datetime-format: Формат даты и времени
   about: Информация
   search: Включить поиск с помощью Dozzle, используя
   using-version: Вы используете версию Dozzle {version}.
diff --git a/locales/tr.yml b/locales/tr.yml
index fbaf9f908ea2..5a8f4411a69c 100644
--- a/locales/tr.yml
+++ b/locales/tr.yml
@@ -18,6 +18,7 @@ label:
   dozzle-version: Dozzle Sürümü
   all: Tümü
   host: Sunucu
+  hosts: Sunucular
   password: Şifre
   username: Kullanıcı Adı
   container-name: Konteyner Adı
diff --git a/locales/zh-tw.yml b/locales/zh-tw.yml
index 3e069f157c65..2b341629d67b 100644
--- a/locales/zh-tw.yml
+++ b/locales/zh-tw.yml
@@ -15,6 +15,7 @@ label:
   dozzle-version: Dozzle 版本
   all: 全部
   host: 主機
+  hosts: 主機
   password: 密碼
   username: 使用者名稱
   container-name: 容器名稱
diff --git a/locales/zh.yml b/locales/zh.yml
index 7c3e2af99fa2..67c97bdfa47f 100644
--- a/locales/zh.yml
+++ b/locales/zh.yml
@@ -6,6 +6,7 @@ toolbar:
   show-all: 显示全部
 label:
   containers: 容器
+  container: 无容器 | 1 容器 | {count} 容器
   running-containers: 运行中的容器
   all-containers: 所有容器
   total-containers: 所有容器
@@ -15,6 +16,7 @@ label:
   dozzle-version: Dozzle版本
   all: 全部
   host: 主机
+  hosts: 主机
   password: 密码
   username: 用户名
   container-name: 容器名称
@@ -69,6 +71,7 @@ settings:
     默认情况下，Dozzle将使用您的浏览器区域设置来格式化时间。系统支持12或24小时制。
   font-size: 字体大小
   color-scheme: 颜色方案
+  datetime-format: 覆盖日期和时间格式
   options: 选项
   show-stopped-containers: 显示已停止的容器
   about: 关于
diff --git a/vite.config.ts b/vite.config.ts
index 50d3e4b0ff51..2f089d28e1cf 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -26,6 +26,7 @@ export default defineConfig(() => ({
     modulePreload: {
       polyfill: false,
     },
+    target: "esnext",
   },
   plugins: [
     VueMacros({


Test patch: