// The single source of truth for this app's locales + the URL-prefix // helpers. `app.config.ts` lists the same codes for the build pipeline; // the [locale] mirror page + the layout's read THIS file. // // Keep SUPPORTED_LOCALES / DEFAULT_LOCALE in sync with `locales` / // `defaultLocale` in app.config.ts. import { useLocation } from '@voltro/web' import en from '../locales/en' import de from '../locales/de' export const SUPPORTED_LOCALES = ['en', 'de'] as const export const DEFAULT_LOCALE = 'en' export type Locale = (typeof SUPPORTED_LOCALES)[number] // The catalogs, keyed by code. The layout picks one to feed the inner // ; `meta` (build-time, per locale) reads one via getCatalog. export const CATALOGS = { en, de } as const // Every catalog mirrors `en`'s keys (defineLocale enforces it), so a // plain string-record over en's keys is the common type both satisfy — // what `meta` reads at build time (`c['meta.home.title']` → string). export type Messages = Record const isSupported = (v: string): v is Locale => (SUPPORTED_LOCALES as ReadonlyArray).includes(v) export const getCatalog = (locale: string): Messages => isSupported(locale) ? CATALOGS[locale] : CATALOGS[DEFAULT_LOCALE] // `/de` → 'de'; `/` → 'en' (default lives at the bare path). export const localeFromPathname = (pathname: string): Locale => { const match = /^\/([a-z]{2})(?:\/|$)/.exec(pathname) return match && isSupported(match[1]!) ? (match[1] as Locale) : DEFAULT_LOCALE } // Reactive: useLocation re-renders on client-side nav, so the layout's // provider swaps catalogs when you move between / and /de without a full // reload. export const useUrlLocale = (): Locale => localeFromPathname(useLocation()) // '/' + 'de' → '/de'; the default locale stays bare ('/'). export const withLocalePrefix = (path: string, locale: string): string => { if (locale === DEFAULT_LOCALE) return path const p = path.startsWith('/') ? path : `/${path}` return p === '/' ? `/${locale}` : `/${locale}${p}` } // '/de' → '/'; '/' → '/'. The inverse of the above, used to keep the // active path when switching language. export const stripLocalePrefix = (pathname: string): string => { const match = /^\/([a-z]{2})(\/.*|$)/.exec(pathname) return match && isSupported(match[1]!) ? match[2] || '/' : pathname }