# 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.