Fix initial i18n render crash on auth pages

Initialize locale messages before the first app render so the auth page does not diff from the fallback language into the detected locale during startup.

Mark the app root as non-translatable and keep the document language synchronized with the active locale to reduce browser translation DOM mutations.
This commit is contained in:
shuaiplus
2026-06-06 19:30:35 +08:00
parent 2d2cbea530
commit 1ee7b0f31b
2 changed files with 14 additions and 3 deletions
+12
View File
@@ -62,6 +62,15 @@ const localeLoaders: Record<Locale, () => Promise<{ default: MessageTable }>> =
es: () => import('./i18n/locales/es'), es: () => import('./i18n/locales/es'),
}; };
function localeToHtmlLang(value: Locale): string {
return value;
}
function syncDocumentLanguage(): void {
if (typeof document === 'undefined') return;
document.documentElement.lang = localeToHtmlLang(locale);
}
async function loadLocaleMessages(next: Locale): Promise<MessageTable> { async function loadLocaleMessages(next: Locale): Promise<MessageTable> {
const cached = loadedMessages.get(next); const cached = loadedMessages.get(next);
if (cached) return cached; if (cached) return cached;
@@ -84,6 +93,8 @@ export async function initI18n(): Promise<void> {
console.error('Failed to load locale, falling back to English:', error); console.error('Failed to load locale, falling back to English:', error);
locale = 'en'; locale = 'en';
activeMessages = await loadFallbackMessages(); activeMessages = await loadFallbackMessages();
} finally {
syncDocumentLanguage();
} }
} }
@@ -143,6 +154,7 @@ export async function setLocale(next: Locale): Promise<void> {
} }
locale = next; locale = next;
activeMessages = nextMessages; activeMessages = nextMessages;
syncDocumentLanguage();
try { try {
localStorage.setItem(LOCALE_STORAGE_KEY, next); localStorage.setItem(LOCALE_STORAGE_KEY, next);
} catch { } catch {
+2 -3
View File
@@ -16,6 +16,7 @@ const queryClient = new QueryClient({
}); });
const root = document.getElementById('root')!; const root = document.getElementById('root')!;
root.setAttribute('translate', 'no');
function renderApp(): void { function renderApp(): void {
render( render(
@@ -26,8 +27,6 @@ function renderApp(): void {
); );
} }
renderApp(); void initI18n().finally(() => {
void initI18n().then(() => {
renderApp(); renderApp();
}); });