mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 21:01:08 +02:00
Final cleanup of references missed in previous rename commits: - Dockerfiles: PUBLIC_MANA_CORE_AUTH_URL → PUBLIC_MANA_AUTH_URL - Go modules: github.com/manacore/* → github.com/mana/* (7 go.mod files) - launchd plists: com.manacore.* → com.mana.* (14 files renamed + content) - Image assets: *_Manacore_AI_Credits* → *_Mana_AI_Credits* (11 files) - .env.example files: ManaCore brand strings → Mana - .prettierignore: stale apps/manacore/* paths → apps/mana/* - Markdown docs (CLAUDE.md, /docs/*): mana-core-auth → mana-auth, etc. Excluded from rename: .claude/, devlog/, manascore/ (historical content), client testimonials, blueprints, npm package refs (@mana-core/*). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
226 lines
5.4 KiB
Markdown
226 lines
5.4 KiB
Markdown
# Internationalization (i18n) im Mana 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 |
|
|
| mana | de, en, es, fr, it | de |
|
|
| cards | 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 `@mana/shared-i18n` verwendet werden (wenn vorhanden).
|
|
|
|
```typescript
|
|
// In index.ts
|
|
import sharedTranslations from '@mana/shared-i18n/de.json';
|
|
|
|
register('de', async () => {
|
|
const local = await import('./locales/de.json');
|
|
return { ...sharedTranslations, ...local.default };
|
|
});
|
|
```
|