import { getLocaleByPath, getRelativeLocaleUrl } from 'astro:i18n'; import { DEFAULT_LOCALE, LOCALES, type Locale } from '@/i18n/config'; import { translate } from '@/i18n/dictionary'; /** * 从 URL 解析语言,委托 Astro 内置的 astro:i18n.getLocaleByPath。 * 无前缀(默认语言)路径会解析回 DEFAULT_LOCALE。 */ export function getLocaleFromUrl(url: URL | string): Locale { const pathname = typeof url === 'string' ? url : url.pathname; try { const locale = getLocaleByPath(pathname); return (LOCALES as readonly string[]).includes(locale) ? (locale as Locale) : DEFAULT_LOCALE; } catch { return DEFAULT_LOCALE; } } /** * 取翻译函数 t():key 即英文原文,按当前语言自动匹配翻译。 * - 英文环境:t('全部的 runway') 直接返回 '全部的 runway'(key 本身) * - 中文环境:t('全部的 runway') 返回字典里的 '全部的 runway'(取不到则回退英文) * - 支持 {name} 形式的插值参数。 */ export function useTranslations(locale: Locale) { function t(key: string, params?: Record): string { return translate(key, locale, params); } return { t, locale }; } /** * 一行取「当前语言 + 翻译函数」,干掉每个页面重复的样板: * const { locale, t } = getI18n(Astro) * 内部用 Astro.currentLocale(与 Layout 判断语言的方式一致), * 取不到时回退默认语言。参数只要求含 currentLocale 字段,避免耦合 Astro 全局类型。 */ export function getI18n(Astro: { currentLocale?: string | undefined }) { const locale = (Astro.currentLocale as Locale) ?? DEFAULT_LOCALE; const { t } = useTranslations(locale); return { locale, t, getRelativeLocaleUrl }; } export { LOCALES, DEFAULT_LOCALE }; export type { Locale };