fix(header): proper DE|EN language switcher + asset cache-busting #7

Merged
Phil merged 2 commits from fix/lang-switcher-design into main 2026-05-31 07:13:16 +00:00
Owner

Was

Der Sprach-Switcher sah live nackt/gestapelt aus. Zwei Ursachen behoben + ordentliches Design (vom Design-Reviewer als Best-Practice bestätigt).

Switcher-Design (Variante B — Inline Text-Toggle)

DE | EN mit Hairline-Divider (zitiert den PL |-Logo-Trenner). Aktive Sprache Ink/dunkel (nicht blau → konkurriert nicht mit dem „Termin buchen"-CTA), inaktive grau → Akzent-Blau im Hover. ≥44px Touch-Targets, :focus-visible-Ring, aria-current, prefers-reduced-motion. Mobile: eigene Zeile im Burger-Menü mit Hairline-Trenner, 48px Targets. Pill/Dropdown verworfen (CTA-Konflikt bzw. Over-Engineering bei 2 Sprachen).

Cache-Busting (Root-Cause)

base.twig hatte einen hartcodierten assetVer = '2026051902' → neue CSS/JS-Builds wurden auf Prod nie frisch geladen (genau warum der Switcher kaputt aussah: alte gecachte CSS). Jetzt filemtime-basiert via kleine Twig-Extension (assetMtime(), neues modules/site) — jeder npm run build erzeugt automatisch eine neue Asset-URL, kein manuelles Hochzählen mehr.

Switcher-URL-Bugfix

Auf /en/ zeigte der DE-Link fälschlich auf /en/ (man kam nicht zurück auf Deutsch). Ursache: entry.localized.eagerly().all() löst .url im Kontext der Request-Site auf. Fix: per-Site-Query .site(site).one() setzt den Site-Scope explizit.

Verifikation (lokal)

  • /, /en/, Artikel DE+EN: Switcher-Links zeigen jeweils korrekt auf die andere Sprachvariante (Artikel-aware, Home-Fallback)
  • assetVer ändert sich bei jedem Build
  • Switcher visuell abgenommen (Desktop + Mobile, Divider/Active-Ink/Hover-Blau)

Refs #4

🤖 Generated with Claude Code

## Was Der Sprach-Switcher sah live nackt/gestapelt aus. Zwei Ursachen behoben + ordentliches Design (vom Design-Reviewer als Best-Practice bestätigt). ### Switcher-Design (Variante B — Inline Text-Toggle) `DE | EN` mit Hairline-Divider (zitiert den `PL |`-Logo-Trenner). Aktive Sprache **Ink/dunkel** (nicht blau → konkurriert nicht mit dem „Termin buchen"-CTA), inaktive grau → Akzent-Blau im Hover. ≥44px Touch-Targets, `:focus-visible`-Ring, `aria-current`, `prefers-reduced-motion`. Mobile: eigene Zeile im Burger-Menü mit Hairline-Trenner, 48px Targets. Pill/Dropdown verworfen (CTA-Konflikt bzw. Over-Engineering bei 2 Sprachen). ### Cache-Busting (Root-Cause) `base.twig` hatte einen **hartcodierten** `assetVer = '2026051902'` → neue CSS/JS-Builds wurden auf Prod nie frisch geladen (genau warum der Switcher kaputt aussah: alte gecachte CSS). Jetzt `filemtime`-basiert via kleine Twig-Extension (`assetMtime()`, neues `modules/site`) — jeder `npm run build` erzeugt automatisch eine neue Asset-URL, kein manuelles Hochzählen mehr. ### Switcher-URL-Bugfix Auf `/en/` zeigte der DE-Link fälschlich auf `/en/` (man kam nicht zurück auf Deutsch). Ursache: `entry.localized.eagerly().all()` löst `.url` im Kontext der Request-Site auf. Fix: per-Site-Query `.site(site).one()` setzt den Site-Scope explizit. ## Verifikation (lokal) - `/`, `/en/`, Artikel DE+EN: Switcher-Links zeigen jeweils korrekt auf die andere Sprachvariante (Artikel-aware, Home-Fallback) - assetVer ändert sich bei jedem Build - Switcher visuell abgenommen (Desktop + Mobile, Divider/Active-Ink/Hover-Blau) Refs #4 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Replaces the opaque pill-style language toggle with a flächenloser
inline text switcher: uppercase Aeion Mono 12px, Ink active state,
grey-blue inactive, accent-blue hover, hairline divider (1px #c7ccd6)
mirroring the PL| logo separator. Touch targets ≥44px desktop,
≥48px mobile. Focus ring 2px blue outline. prefers-reduced-motion
respected. Mobile inherits border-block-start separator.

Replaces the hardcoded prod asset version '2026051902' with automatic
filemtime-based versioning via a new SiteModule + SiteTwigExtension
(modules/site/). The assetMtime('@webroot/dist/main.min.css') Twig
function returns the file's Unix mtime, which changes on every build,
so no manual version bumps are ever needed. Module bootstrapped via
config/app.web.php to guarantee registration before first Twig compile.

Refs #4

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
entry.localized.eagerly().all() liefert .url im Request-Site-Kontext,
weshalb der DE-Link von /en/ auf /en/ zeigte statt auf /.

Per-Site-Query mit .site(site).one() erzwingt den korrekten Site-Scope
für die URL-Auflösung. Vorheriges Eager-Loading-Pattern entfernt.

Refs #4

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Phil merged commit 5193e0e62e into main 2026-05-31 07:13:16 +00:00
Phil deleted branch fix/lang-switcher-design 2026-05-31 07:13:16 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Phil/philflow.io!7
No description provided.