Files
windwiderstand.de/.cursor/rules/translations-i18n.mdc
T

42 lines
2.3 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.