import { writable, derived, get } from "svelte/store" import { location } from "./store" /** * Supported languages configuration. * Add more languages as needed for your project. */ export const SUPPORTED_LANGUAGES = ["de", "en"] as const export type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number] export const DEFAULT_LANGUAGE: SupportedLanguage = "de" export const LANGUAGE_LABELS: Record = { de: "Deutsch", en: "English", } /** * Route translations for localized URLs. * Add entries for routes that need translated slugs. * Example: { about: { de: "ueber-uns", en: "about" } } */ export const ROUTE_TRANSLATIONS: Record> = { // Add your route translations here: // about: { de: "ueber-uns", en: "about" }, } export const getLocalizedRoute = (canonicalRoute: string, lang: SupportedLanguage): string => { const translations = ROUTE_TRANSLATIONS[canonicalRoute] if (translations && translations[lang]) { return translations[lang] } return canonicalRoute } export const getCanonicalRoute = (localizedSegment: string): string => { for (const [canonical, translations] of Object.entries(ROUTE_TRANSLATIONS)) { for (const translated of Object.values(translations)) { if (translated === localizedSegment) { return canonical } } } return localizedSegment } /** * Extract the language code from a URL path. * Returns null if no valid language prefix is found. */ export const extractLanguageFromPath = (path: string): SupportedLanguage | null => { const match = path.match(/^\/([a-z]{2})(\/|$)/) if (match && SUPPORTED_LANGUAGES.includes(match[1] as SupportedLanguage)) { return match[1] as SupportedLanguage } return null } export const stripLanguageFromPath = (path: string): string => { const lang = extractLanguageFromPath(path) if (lang) { const stripped = path.slice(3) return stripped || "/" } return path } export const getRoutePath = (fullPath: string): string => { const stripped = stripLanguageFromPath(fullPath) if (stripped === "/" || stripped === "") { return "/" } const segments = stripped.split("/").filter(Boolean) if (segments.length > 0) { const canonicalFirst = getCanonicalRoute(segments[0]) if (canonicalFirst !== segments[0]) { segments[0] = canonicalFirst return "/" + segments.join("/") } } return stripped } /** * Derived store: current language based on URL. */ export const currentLanguage = derived(location, ($location) => { const path = $location.path || "/" return extractLanguageFromPath(path) || DEFAULT_LANGUAGE }) /** * Writable store for the selected language. */ export const selectedLanguage = writable(DEFAULT_LANGUAGE) if (typeof window !== "undefined") { const initialLang = extractLanguageFromPath(window.location.pathname) if (initialLang) { selectedLanguage.set(initialLang) } } if (typeof window !== "undefined") { location.subscribe(($loc) => { const lang = extractLanguageFromPath($loc.path) if (lang) { selectedLanguage.set(lang) } }) } /** * Get the localized path for a given route and language. */ export const localizedPath = (path: string, lang?: SupportedLanguage): string => { const language = lang || get(currentLanguage) if (path === "/" || path === "") { return `/${language}` } let cleanPath = stripLanguageFromPath(path) cleanPath = cleanPath.startsWith("/") ? cleanPath : `/${cleanPath}` const segments = cleanPath.split("/").filter(Boolean) if (segments.length > 0) { const canonicalFirst = getCanonicalRoute(segments[0]) const localizedFirst = getLocalizedRoute(canonicalFirst, language) segments[0] = localizedFirst } const translatedPath = "/" + segments.join("/") return `/${language}${translatedPath}` } /** * Derived store for localized href. */ export const localizedHref = (path: string) => { return derived(currentLanguage, ($lang) => localizedPath(path, $lang)) } export const isValidLanguage = (lang: string): lang is SupportedLanguage => { return SUPPORTED_LANGUAGES.includes(lang as SupportedLanguage) } /** * Get the browser's preferred language, falling back to default. */ export const getBrowserLanguage = (): SupportedLanguage => { if (typeof navigator === "undefined") { return DEFAULT_LANGUAGE } const browserLangs = navigator.languages || [navigator.language] for (const lang of browserLangs) { const code = lang.split("-")[0].toLowerCase() if (isValidLanguage(code)) { return code } } return DEFAULT_LANGUAGE } /** * Get URL for switching to a different language. */ export const getLanguageSwitchUrl = (newLang: SupportedLanguage): string => { const currentPath = typeof window !== "undefined" ? window.location.pathname : "/" const canonicalPath = getRoutePath(currentPath) return localizedPath(canonicalPath, newLang) }