/** * Клиент для Localization Service. * Принудительно русский язык везде. */ const LOCALE_API = '/api/locale'; const TRANSLATIONS_API = '/api/translations'; export interface LocalizationContext { locale: string; language: string; region: string | null; countryCode: string | null; timezone: string | null; source: 'geo' | 'accept-language' | 'client' | 'fallback'; } const collectClientData = () => { if (typeof window === 'undefined') return {}; const nav = navigator; return { client: { language: nav.language, languages: nav.languages ? [...nav.languages] : undefined, }, }; }; /** * Получить locale (серверный вызов — без client data). */ export async function fetchLocale(): Promise { const res = await fetch(LOCALE_API); if (!res.ok) throw new Error('Failed to fetch locale'); return res.json(); } /** * Получить locale с данными клиента (браузер language). */ export async function fetchLocaleWithClient(): Promise { const clientData = collectClientData(); const res = await fetch(LOCALE_API, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(clientData), }); if (!res.ok) throw new Error('Failed to fetch locale'); return res.json(); } /** Принудительно русский язык везде */ export async function fetchLocaleWithGeoFirst(): Promise { return { locale: 'ru', language: 'ru', region: null, countryCode: null, timezone: null, source: 'fallback', }; } import { getEmbeddedTranslations, translationLocaleFor, } from './localization/embeddedTranslations'; /** * Получить переводы для locale. * При недоступности API использует встроенные переводы. */ export async function fetchTranslations( locale: string, ): Promise> { const fetchLocale = translationLocaleFor(locale); try { const res = await fetch( `${TRANSLATIONS_API}/${encodeURIComponent(fetchLocale)}`, ); if (res.ok) return res.json(); } catch { /* API недоступен */ } return getEmbeddedTranslations(locale); } /** * Получить locale и переводы одним вызовом. */ export async function fetchLocalization(): Promise<{ locale: LocalizationContext; translations: Record; }> { const locale = await fetchLocaleWithClient(); const translations = await fetchTranslations(locale.locale); return { locale, translations }; }