// SSR-плагин: по ISO-коду клиента резолвит имя страны в useState('clientCountryName') // для гео-заголовка. Полный список стран в payload не кладётся (его лениво догружает // селектор языка на клиенте). Результат кэшируется в память процесса. import type { ICountries } from '../types'; /** Опции легаси-кук — нужны только чтобы их погасить (см. ниже) */ const LEGACY_COOKIE_OPTS = { path: '/', secure: true, sameSite: 'lax' as const }; const cache = new Map | null>>(); function buildNameByIso(data: ICountries): Map { const nameByIso = new Map(); for (const item of data.countries) { for (const code of item.isoCodes) { nameByIso.set(code.toLowerCase(), item.title); } } return nameByIso; } function getNameByIso(language: string, domain: string): Promise | null> { const key = `${language}|${domain}`; let promise = cache.get(key); if (!promise) { promise = $fetch('/api/dictionaries/countries', { headers: { 'x-language': language, 'x-domain': domain }, }) .then(data => (data?.countries?.length ? buildNameByIso(data) : null)) .catch(() => { cache.delete(key); return null; }); cache.set(key, promise); } return promise; } export default defineNuxtPlugin(async () => { const event = useRequestEvent(); const code = ((event?.context?.clientCountryCode as string | undefined) || '').trim().toLowerCase(); const countryName = useState('clientCountryName', () => ''); // Имя страны больше не кешируется в куках: пара `clientCountryName` + // `clientCountryNameCode` умела разъезжаться с кодом страны (заголовок писал одну // страну, флаг и селектор показывали другую), а выигрыш был только в одном // сетевом запросе на холодный процесс. Старые куки гасим, чтобы не висели год. const legacyName = useCookie('clientCountryName', LEGACY_COOKIE_OPTS); const legacyNameCode = useCookie('clientCountryNameCode', LEGACY_COOKIE_OPTS); if (legacyName.value) legacyName.value = null; if (legacyNameCode.value) legacyNameCode.value = null; // Резолвим только имя текущей страны для гео-заголовка. Полный список стран // НЕ кладём в useState (не сериализуем в payload) — language.vue догружает // его лениво на клиенте при открытии селектора. if (!code) return; const language = useRequestHeaders(['x-language'])['x-language'] ?? ''; const domain = useRuntimeConfig().public.xDomain as string; const nameByIso = await getNameByIso(language, domain); if (!nameByIso) return; countryName.value = nameByIso.get(code) || ''; });