---
description: Übersetzungssystem (i18n) – Keys, CMS, Nutzung in Astro und Svelte
globs: "src/lib/translations.ts,**/Layout.astro,src/pages/**/*.astro,src/components/**/*.svelte,src/middleware.ts"
alwaysApply: false
---

# Übersetzungssystem (i18n)

Alle sichtbaren UI-Texte kommen aus dem CMS (RustyCMS) über das Translation-Bundle.

## Quelle

- **CMS:** Translation-Bundle über API (Single Source of Truth). Slug `app`, geladen in der Middleware mit `_resolve=all`.
- **Slug:** Konstante `TRANSLATION_BUNDLE_SLUG = "app"` in `src/lib/constants.ts`.
- **Middleware:** `src/middleware.ts` lädt das Bundle einmal pro Request und setzt `Astro.locals.translations`.

## Keys definieren

1. **Key in `src/lib/translations.ts`** in das Array `TRANSLATION_KEYS` eintragen (damit `T.key_name` und Typ `TranslationKey` existieren).
2. **String in RustyCMS** in `content/de/translation_bundle/app.json5` unter `strings` eintragen. Platzhalter: `{{name}}` wird durch `t(..., { name: value })` ersetzt.

## Nutzung

### In Astro (.astro)

- `translations = Astro.locals.translations ?? {}`
- `t(translations, T.xy)` oder mit Ersetzungen: `t(translations, T.xy, { count: 5 })`
- Breadcrumbs: optional `translationKey: T.nav_start` statt `label: "Start"`; Layout löst das mit `t(translations, item.translationKey)` auf.

### In Svelte

- **Innerhalb von TranslationProvider** (z. B. Header, Footer): `const t = useTranslate();` dann `t(T.xy)`.
- **client:load-Inseln (Astro Islands):** `useTranslate()` hat keinen Zugriff auf den Svelte-Context, und beim SSR gibt es kein `window` → Übersetzungen fehlen, es erscheint der Key (z. B. `blog_tag_all`).  
  **Lösung:** Übersetzungen immer als Prop von der Astro-Seite übergeben und die statische `t()` nutzen:
  - Komponente: Prop `translations?: Translations`; keine `useTranslate()`, sondern lokale Hilfsfunktion `t(key, replacements) => t(translations ?? null, key, replacements)` mit `t` aus `../lib/translations`.
  - Astro-Seite: `<BlogOverview ... translations={translations} />` mit `translations = Astro.locals.translations ?? {}`.
  - Siehe `BlogOverview.svelte` als Referenz.

### Neue UI-Texte

Keine hartkodierten deutschen/englischen Sätze in Komponenten oder Seiten. Stattdessen: Key in `TRANSLATION_KEYS` + Eintrag in `app.json5`, dann überall `t(translations, T.key)` bzw. `t(T.key)` nutzen.
