60 lines
2.0 KiB
Markdown
60 lines
2.0 KiB
Markdown
# Multilingual (i18n)
|
|
|
|
## Recommended approach: Locale as folder (implemented)
|
|
|
|
Content per language in separate folders:
|
|
|
|
```
|
|
content/
|
|
de/
|
|
page/
|
|
home.json5
|
|
about.json5
|
|
post/
|
|
example-post.json5
|
|
en/
|
|
page/
|
|
home.json5
|
|
about.json5
|
|
post/
|
|
example-post.json5
|
|
```
|
|
|
|
- **Same slug per language** (e.g. `home` in DE and EN).
|
|
- **API:** `?_locale=de` or `?_locale=en`. If parameter is missing, default locale is used.
|
|
- **Configuration:** `RUSTYCMS_LOCALES=de,en` enables the mode; **first locale = default** (e.g. `de`).
|
|
- **Without `RUSTYCMS_LOCALES`:** Previous behavior (single language). Content remains under `content/{collection}/` (no locale folder).
|
|
|
|
## Activation
|
|
|
|
```bash
|
|
# .env or export
|
|
RUSTYCMS_LOCALES=de,en
|
|
```
|
|
|
|
On startup you'll see e.g.: `Multilingual: locales ["de", "en"] (default: de)`.
|
|
|
|
## API usage
|
|
|
|
```bash
|
|
# Default locale (first in RUSTYCMS_LOCALES, e.g. de)
|
|
GET /api/content/page/home
|
|
|
|
# Explicit locale
|
|
GET /api/content/page/home?_locale=en
|
|
GET /api/content/page?_page=1&_per_page=50&_locale=en
|
|
```
|
|
|
|
Response still has the same structure; only the content is locale-dependent. For POST/PUT/DELETE, `_locale` can be passed as a query parameter so the entry is created/updated/deleted in the correct locale.
|
|
|
|
## Optional extensions
|
|
|
|
- **page_config per locale:** e.g. `content/de/page_config/default.json5` and `content/en/page_config/default.json5` for locale-specific SEO, footer text, etc.
|
|
- **Available locales in API:** e.g. `GET /api/locales` → `["de","en"]` (from config).
|
|
- **hreflang / languageAlternates:** derive in frontend from page config or known locales (e.g. already considered in `@types/SeoProps.ts`).
|
|
|
|
## Alternatives (not implemented)
|
|
|
|
- **Locale as field in entry:** Entry with `locale: "de"`, slug unique per language (e.g. `home-de`, `home-en`). Works without store changes, but same logical content has different slugs.
|
|
- **Translations in one entry:** File with `translations: { de: {...}, en: {...} }`. No extra folders, but schema and API (filter, resolve) become more complex.
|