# Phase 15: Locale Detection & Routing - Context **Gathered:** 2026-02-02 **Status:** Ready for planning ## Phase Boundary Enable users to browse the site in their preferred language through URL prefixes (/pl/, /de/) with automatic browser detection and persistent preference. Build on existing Golem15\Translate plugin infrastructure (LocalePicker, LocaleMiddleware, Translator). ## Implementation Decisions ### URL structure - Use WinterCMS standard pattern: visiting `/pl/about` switches locale to Polish, then all subsequent navigation uses normal URLs without prefix (locale persists via session) - Default locale (English) is prefix-free: `/jobs` not `/en/jobs` - Config: `prefixDefaultLocale: false` for cleaner default language URLs - When URL contains explicit locale prefix, set `locale_manually_set` cookie (same as language picker does) - Automatic hreflang tags via AlternateHrefLangElements component in all layouts ### Detection behavior - Browser detection via Accept-Language header on FIRST VISIT ONLY - Once user has session/cookie, never auto-detect again - Primary language matching: `de-DE` → `de`, `pl-PL` → `pl` (extract first 2 chars) - Priority cascade (already in middleware): URL → User DB preference → Session → Browser detection → Default - Logged-in user's `preferred_locale` from DB always wins over session/browser (but URL prefix still overrides for that request) ### Language switcher UX - Location: Header, near user menu (top right) - Style: Dropdown with full text ("English ▼") - Language names in native form: "Polski", "Deutsch", "English" - Switching preserves current page (stay on `/jobs/123`, just change language) - LocalePicker component with `forceUrl: false` (standard pattern) ### Preference persistence - Guest users: 1-year cookie for locale preference - Language picker usage saves to DB for logged-in users (auto-update `preferred_locale`) - URL prefix visit does NOT update DB preference (only affects session) - Users set their preferred locale during onboarding (already captured in profile) - Preferred locale dropdown in user profile settings (Profile section, not Family Settings) ### Language suggestion banner - Show non-intrusive banner when: browser language differs from current page locale AND user hasn't manually selected - Example: German browser visits `/pl/jobs` from shared link → show "Diese Seite ist auf Deutsch verfügbar" banner - Dismissing banner sets 1-week cookie, don't show again until expires - Only show once per session even without explicit dismissal ### Claude's Discretion - Exact banner styling and positioning - Cookie names and implementation details - Component registration and partial structure - Mobile responsiveness of language switcher ## Specific Ideas - "I loved WinterCMS approach" — locale switching via URL prefix, then normal navigation without prefixes - Must be fully compatible with existing Translate and User plugins — no breaking changes - Language picker behavior should match URL prefix behavior (both set manual-selection cookie) ## Deferred Ideas None — discussion stayed within phase scope --- *Phase: 15-locale-detection-routing* *Context gathered: 2026-02-02*