diff --git a/frontend/src/hooks.server.ts b/frontend/src/hooks.server.ts index 6271507e..fc5d3a71 100644 --- a/frontend/src/hooks.server.ts +++ b/frontend/src/hooks.server.ts @@ -2,9 +2,34 @@ import { redirect, type Handle, type HandleFetch } from '@sveltejs/kit'; import { paraglideMiddleware } from '$lib/paraglide/server'; import { sequence } from '@sveltejs/kit/hooks'; import { env } from 'process'; +import { cookieName, cookieMaxAge, locales } from '$lib/paraglide/runtime'; const PUBLIC_PATHS = ['/login', '/logout']; +function detectLocale(acceptLanguage: string): string | null { + const preferred = acceptLanguage + .split(',') + .map((part) => { + const [lang, q] = part.trim().split(';q='); + return { lang: lang.trim().split('-')[0].toLowerCase(), q: q ? parseFloat(q) : 1 }; + }) + .sort((a, b) => b.q - a.q); + for (const { lang } of preferred) { + if ((locales as readonly string[]).includes(lang)) return lang; + } + return null; +} + +const handleLocaleDetection: Handle = ({ event, resolve }) => { + if (!event.cookies.get(cookieName)) { + const locale = detectLocale(event.request.headers.get('accept-language') ?? ''); + if (locale) { + event.cookies.set(cookieName, locale, { path: '/', sameSite: 'lax', maxAge: cookieMaxAge }); + } + } + return resolve(event); +}; + const handleAuth: Handle = async ({ event, resolve }) => { const isPublic = PUBLIC_PATHS.some((p) => event.url.pathname.startsWith(p)); if (!isPublic && !event.locals.user) { @@ -74,4 +99,4 @@ export const handleFetch: HandleFetch = async ({ event, request, fetch }) => { return fetch(request); }; -export const handle = sequence(userGroup, handleAuth, handleParaglide); +export const handle = sequence(userGroup, handleAuth, handleLocaleDetection, handleParaglide);