managarten/docs/I18N.md

226 lines
5.5 KiB
Markdown

# Internationalization (i18n) im Manacore Monorepo
Alle Web-Projekte im Monorepo verwenden **svelte-i18n** für die Internationalisierung. Diese Dokumentation beschreibt die einheitliche Implementierung.
## Übersicht
| Projekt | Sprachen | Default |
|---------|----------|---------|
| maerchenzauber | de, en, es, fr, it | de |
| manacore | de, en, es, fr, it | de |
| manadeck | de, en, es, fr, it | de |
| memoro | de, en, es, fr, it | de |
| picture | de, en | de |
| uload | de, en, es, fr, it | en |
## Projektstruktur
Jedes Web-Projekt hat die folgende i18n-Struktur:
```
apps/web/
└── src/
└── lib/
└── i18n/
├── index.ts # Initialisierung & Konfiguration
└── locales/
├── de.json # Deutsche Übersetzungen
├── en.json # Englische Übersetzungen
├── es.json # Spanische Übersetzungen (optional)
├── fr.json # Französische Übersetzungen (optional)
└── it.json # Italienische Übersetzungen (optional)
```
## Implementierung
### 1. index.ts - Konfiguration
```typescript
import { browser } from '$app/environment';
import { init, register, locale, waitLocale } from 'svelte-i18n';
// Sprachen registrieren
register('de', () => import('./locales/de.json'));
register('en', () => import('./locales/en.json'));
// ... weitere Sprachen
// Unterstützte Sprachen
export const supportedLocales = ['de', 'en', 'es', 'fr', 'it'] as const;
export type SupportedLocale = (typeof supportedLocales)[number];
const defaultLocale = 'de';
// Initiale Sprache ermitteln
function getInitialLocale(): SupportedLocale {
if (browser) {
// 1. localStorage prüfen
const stored = localStorage.getItem('locale');
if (stored && supportedLocales.includes(stored as SupportedLocale)) {
return stored as SupportedLocale;
}
// 2. Browser-Sprache prüfen
const browserLang = navigator.language.split('-')[0];
if (supportedLocales.includes(browserLang as SupportedLocale)) {
return browserLang as SupportedLocale;
}
}
return defaultLocale;
}
// i18n initialisieren
init({
fallbackLocale: defaultLocale,
initialLocale: getInitialLocale()
});
// Sprache ändern und speichern
export function setLocale(newLocale: SupportedLocale) {
locale.set(newLocale);
if (browser) {
localStorage.setItem('locale', newLocale);
}
}
export { waitLocale };
```
### 2. Locale-Dateien (JSON)
Die Übersetzungen werden als flache oder verschachtelte JSON-Objekte gespeichert:
```json
{
"nav_login": "Anmelden",
"nav_register": "Registrieren",
"common": {
"save": "Speichern",
"cancel": "Abbrechen"
}
}
```
### 3. Verwendung in Svelte-Komponenten
```svelte
<script lang="ts">
import { t } from 'svelte-i18n';
</script>
<!-- Einfacher Key -->
<button>{$t('nav_login')}</button>
<!-- Verschachtelter Key -->
<button>{$t('common.save')}</button>
<!-- Mit Parametern -->
<p>{$t('welcome', { values: { name: 'Max' } })}</p>
```
### 4. Language Switcher
```svelte
<script lang="ts">
import { locale } from 'svelte-i18n';
import { setLocale, supportedLocales } from '$lib/i18n';
const languages = [
{ code: 'de', name: 'Deutsch', flag: '🇩🇪' },
{ code: 'en', name: 'English', flag: '🇬🇧' }
];
</script>
{#each languages as lang}
<button
onclick={() => setLocale(lang.code)}
class:active={$locale === lang.code}
>
{lang.flag} {lang.name}
</button>
{/each}
```
## Neues Projekt einrichten
1. **svelte-i18n installieren:**
```bash
pnpm add svelte-i18n
```
2. **i18n-Ordner erstellen:**
```bash
mkdir -p src/lib/i18n/locales
```
3. **index.ts kopieren** von einem bestehenden Projekt und anpassen
4. **Locale-Dateien erstellen** (de.json, en.json, etc.)
5. **In +layout.svelte importieren:**
```svelte
<script>
import '$lib/i18n';
</script>
```
## Neue Übersetzung hinzufügen
1. Key in allen Locale-Dateien hinzufügen:
```json
// de.json
{ "new_key": "Neue Übersetzung" }
// en.json
{ "new_key": "New translation" }
```
2. In Komponente verwenden:
```svelte
{$t('new_key')}
```
## Best Practices
- **Keys:** Snake_case verwenden (`nav_login`, `home_title`)
- **Namespacing:** Präfixe für Bereiche (`auth_`, `nav_`, `home_`, `toast_`)
- **Fallback:** Immer `fallbackLocale` setzen
- **SSR:** `waitLocale()` in Server-Load-Funktionen verwenden
- **Konsistenz:** Gleiche Keys in allen Projekten für gemeinsame Elemente
## Fehlerbehebung
### Übersetzung wird nicht angezeigt
1. Prüfen ob Key in allen Locale-Dateien existiert
2. Prüfen ob `$lib/i18n` importiert wurde
3. Browser-Cache leeren
### SSR-Fehler
```typescript
// In +layout.ts oder +page.ts
import { waitLocale } from '$lib/i18n';
export const load = async () => {
await waitLocale();
return {};
};
```
### Sprache wechselt nicht
Prüfen ob `locale.set()` aufgerufen wird und localStorage Zugriff erlaubt ist.
## Shared i18n Package
Für gemeinsame Übersetzungen zwischen Projekten kann das Package `@manacore/shared-i18n` verwendet werden (wenn vorhanden).
```typescript
// In index.ts
import sharedTranslations from '@manacore/shared-i18n/de.json';
register('de', async () => {
const local = await import('./locales/de.json');
return { ...sharedTranslations, ...local.default };
});
```