Zum Inhalt springen

Navigation und Sprachen

Navigation und Sprachen hängen zusammen: Die navigation-Sammlung hält je Sprache einen Baum, content hält je Sprache einen Eintrag. Suchbegriffe: Navigation anlegen, Sprache umschalten, translationKey.

api/collections/navigation.yml kennt genau vier Singleton-Bäume: type (header, footer) mal language (de, en) — abgesichert per Unique-Index type_language.

navigation.yml — Felder (gekürzt)
# navigation.yml — Felder (gekürzt)
fields:
- name: language # de | en, Pflicht
- name: type # header | footer, Pflicht
- name: elements # object[]: {name, page?, external?, externalUrl?, hash?, elements?}
Element-Art Felder Beispiel
Intern name + page (= content-ID) {name: "Start", page: "<content.id>"}
Extern name + external: true + externalUrl {name: "Blog", external: true, externalUrl: "https://…"}
Anker zusätzlich hash ohne #, Muster ^[a-zA-Z0-9_-]+$ {name: "Kontakt", page: "<id>", hash: "kontakt"}
Unterpunkt geschachtelt in elements.elements Header max. 2 Ebenen, Footer max. 1
  1. Lege je Sprache einen Header und einen Footer an, je mit active:true (Pflicht trotz fehlendem Schema-Feld — siehe Kasten unten).

  2. Löse Seiten mit Lookup auf:

    Seiten per Lookup auflösen
    GET …/navigation?lookup=elements.page:content
  3. Baue den Link aus dem Lookup: href = lokalisierter _lookup.page.path plus hash. Den /de-Präfix nie in die DB schreiben.

content.yml nutzt Entry-i18n: eine Sprache je Eintrag, verbunden über den Schlüssel.

content.yml — i18n-Block (gekürzt)
# content.yml — i18n-Block (gekürzt)
meta:
i18n:
entry:
languageField: lang
groupField: translationKey
Regel Konkret
lang Sprachkürzel, z. B. de, en
translationKey Pflicht, z. B. home, ueber-uns — pro Sprache eindeutig (Unique-Index translationKey + lang)
Zweiter Datensatz ohne Schlüssel Kollidiert auf null — vergebe immer einen eindeutigen translationKey je Sprache
path Ohne Sprachpräfix gespeichert (/ueber-uns), URL mit Präfix (/de/ueber-uns)
alternativePaths[].path Alte Pfade, gleiches Muster wie path

Die Feld-i18n (Tabs je Feld, Test-Plan 34-i18n-fields) und Entry-i18n (eine Sprache je Eintrag, Test-Plan 35-entry-i18n) pflegst du im tibi-admin; das Datenmodell aus Projekt-Sicht ist immer lang + translationKey.

Pfad-Muster für path und alternativePaths
^/[a-z0-9-/]*$ → gilt für path und alternativePaths[].path
  • Nur Kleinbuchstaben, Ziffern, - und /; keine Großbuchstaben, keine Umlaute (/ueber-uns statt /Über-uns).
  • Unique-Index path + lang: gleicher Pfad in de und en ist okay, zweimal in de nicht.
  • SSR streift den Präfix vor der Suche ab und liefert die kanonische URL zurück (hooks/config.js → ssrValidatePath).

Ohne active: true bleiben Abfragen öffentlich leer — je Sammlung wirkt sich das anders aus (kanonische Tabelle unter Rechte und Tokens): content wird weggefiltert, medialib-Lookups bleiben leer (Dateien und Bilder), Header/Footer sind leer.

Navigation je Sprache prüfen (anonym)
GET …/navigation?filter={"language":"de"}
GET …/navigation?filter={"language":"en"}
# anonym (ohne Token) müssen beide je einen Header und einen Footer liefern
Fehlerbild Ursache Lösung
Öffentliche Nav leer, mit Token voll active:true fehlt Auf allen vier Bäumen setzen
409 beim zweiten Spracheintrag translationKey fehlt oder doppelt Eindeutigen Schlüssel je Sprache vergeben
400 beim Speichern Pfad mit Großbuchstaben/Umlaut Kleinschreiben, Muster einhalten
Falsche Sprache im SSR lang-Feld passt nicht zum Präfix lang und URL-Präfix angleichen

Weiter: Lesen und suchen, Dateien und Bilder, Rechte und Tokens.

Verifiziert am e3f92eb 2026-10-17 (tibi-svelte-starter), am 2b091d8 2026-10-17 (tibi-admin-nova, Test-Pläne 34-i18n-fields, 35-entry-i18n)