2026-01-10 09:41:57 +01:00

76 lines
1.9 KiB
TypeScript

import { useEffect, useState } from 'react'
import { setLocale, getLocale, loadTranslations, t, type Locale } from '@/lib/i18n'
export function useI18n(locale: Locale = 'fr'): {
loaded: boolean
locale: Locale
t: (key: string, params?: Record<string, string | number>) => string
} {
const [loaded, setLoaded] = useState(false)
const [currentLocale, setCurrentLocale] = useState<Locale>(getLocale())
useEffect(() => {
void initializeI18n({
locale,
setLoaded,
setCurrentLocale,
})
}, [locale])
return { loaded, locale: currentLocale, t }
}
async function initializeI18n(params: {
locale: Locale
setLoaded: (value: boolean) => void
setCurrentLocale: (value: Locale) => void
}): Promise<void> {
try {
const savedLocale = await readSavedLocale()
const initialLocale = isSupportedLocale(savedLocale) ? savedLocale : params.locale
await loadAllTranslations()
setLocale(initialLocale)
params.setCurrentLocale(initialLocale)
} catch (e) {
console.error('Error loading translations:', e)
} finally {
params.setLoaded(true)
}
}
function isSupportedLocale(value: unknown): value is Locale {
return value === 'fr' || value === 'en'
}
async function readSavedLocale(): Promise<Locale | null> {
try {
const { localeStorage } = await import('@/lib/localeStorage')
await localeStorage.migrateFromLocalStorage()
return localeStorage.getLocale()
} catch {
return null
}
}
async function loadAllTranslations(): Promise<void> {
const [frText, enText] = await Promise.all([
fetchTranslationText('/locales/fr.txt'),
fetchTranslationText('/locales/en.txt'),
])
if (frText) {
void loadTranslations('fr', frText)
}
if (enText) {
void loadTranslations('en', enText)
}
}
async function fetchTranslationText(url: string): Promise<string | undefined> {
const response = await globalThis.fetch(url)
if (!response.ok) {
return undefined
}
return response.text()
}