Ein Ref wird zu einer Version. Richte eine Quelle auf Tags, und jeder davon wird
veröffentlicht — mit einem Versionssegment in der URL und einem Eintrag im
Umschalter.

Refs erfordern ein explizites `repo`, auch für einen anderen Ref dieses
Repositorys. Ohne `repo` liest eine Quelle den aktuellen lokalen Checkout und
lehnt `refs` (einschließlich `latest`) sowie lokale `ref`-Overrides pro Sprache
ab. `origin.repo` und `origin.ref` liefern nur Herkunftslinks; sie wählen keine
Inhalte aus. Eine Sprache mit eigenem explizitem `repo` darf einen eigenen `ref`
wählen. Für lokale Versionen dienen `version` an Quellen mit getrennten Ordnern
oder dateibasierte `versions` eines generierten Abschnitts.

## Schritte

::steps
1. **Liste die Refs auf.** Eine bloße Zeichenkette ist ein **Branch**. Ein Tag
   muss das sagen — git hält beide in getrennten Namensräumen, und einen Tag
   unter `refs/heads` anzufragen lässt den Build scheitern.

   ```ts [app/app.config.ts]
   sources: [
     {
       repo: 'acme/api',
       path: 'docs',
       refs: [
         { branch: 'main', status: 'upcoming' },
         { tag: 'v2.0.0' },
         { tag: 'v1.4.0' },
         { tag: 'v0.9.0', status: 'eol' }
       ]
     }
   ],
   sourceOptions: { defaultRef: 'v2.0.0' }
   ```

2. **Benenne den Standard.** `defaultRef` ist der Ref, der ohne Versionspräfix
   ausgeliefert wird, und der, auf den Suchmaschinen gelenkt werden. Ungesetzt
   ist es der erste in der Liste — was selten das ist, was du willst, wenn die
   Liste mit einem Branch beginnt.

3. **Gib den Lebenszyklus an, wo er sich nicht ableiten lässt.** Semver ordnet
   Tags, „älter als der Standard“ braucht also keine Hilfe. Einen Branch gegen
   einen Tag kann es nicht einordnen: `main` ist `upcoming`, und ohne diese
   Angabe wird seinem Leser gesagt, er solle auf eine Version aktualisieren, die
   älter ist als das, was er liest.

4. **Entdecke Releases, wenn du die Liste nicht bei jedem Release bearbeiten
   willst.** Lege fest, wie viel Historie adressierbar bleibt: alle Releases,
   der neueste Patch jeder Minor-Linie oder der neueste Release jeder Major-Linie.

   ```ts
   releases: { select: 'minor' },
   refs: [{ branch: 'main', status: 'upcoming' }]
   ```

   `all`, `minor` und `major` sind Richtlinien für beständige URLs.
   Pre-Releases bleiben ausgeschlossen, bis `prereleases: true` sie einbezieht.
   Für genau einen mitwandernden Release bleibt `'latest'` verfügbar.

5. **Markiere die Versionsanforderung einer Seite im Text**, wo ein Leser, der
   eine Version ansieht, die anderen nicht sehen kann:

   ```md
   ### Wiederholungen :since{version="v2.0.0"}
   ```

::

## Wie grob eine Version ist

Der Name ist **die Entscheidung der Site, nicht des Mechanismus**. Sie ist hier
besonders wichtig: Jeder Link auf deine Dokumentation wird ihn tragen.

**Eine Linie pro Version, als Branch.** So machen es Laravel, Symfony und Django:
`11.x`, `10.x` und `9.x` sind fortlaufend aktualisierte Branches. Ein Patch-Release
ändert nichts an der URL.

```ts [app/app.config.ts]
sources: [
  {
    repo: 'acme/api',
    path: 'docs',
    refs: [
      { branch: '12.x', status: 'upcoming' },
      '11.x',
      { branch: '10.x', status: 'deprecated' },
      { branch: '9.x', status: 'eol' }
    ]
  }
],
sourceOptions: { defaultRef: '11.x' }
```

Eine bloße Zeichenkette **ist** ein Branch; nur ein Tag muss das ausdrücklich sagen.

**Eine Linie pro Version, aus Tags.** Ist das veröffentlichte Release ein Tag,
soll die URL aber nicht mit jedem Patch wechseln, benennt `label` es um:

```ts
refs: [
  { tag: 'v2.4.1', label: 'v2' },
  { tag: 'v1.9.3', label: 'v1', status: 'deprecated' }
]
```

**Jedes Release als eigene Version.** `{ tag: 'v2.4.1' }` ohne Label. Jede Version
bleibt dauerhaft zitierbar, und der Umschalter wächst um einen Eintrag pro Release.
Für eine Spezifikation passt das, für ein Handbuch nicht.

Dieselben Richtlinien lassen sich aus Tags pflegen, statt sie in der
Konfiguration zu wiederholen:

```ts
// Jedes dauerhaft zitierbare Release.
releases: { select: 'all' }

// Oder der neueste Patch jeder langfristigen Minor-Linie.
releases: { select: 'minor' }

// Oder ein aktuelles Release je Major-Linie.
releases: { select: 'major' }
```

Das neueste ausgewählte Release ist der Standard, sofern nicht ein expliziter
Ref mit `default: true` oder `sourceOptions.defaultRef` etwas anderes festlegt.
Passt kein Tag zur Auswahl, scheitert der Build; ein unerreichbares Repository
wird als Git-Fehler gemeldet und nicht mit einer leeren Auswahl verwechselt.

Dieselbe Wahl gilt für einen Abschnitt mit eigenen Versionen: `version: 'v2'`
oder `version: '2.4.1'`, mit genau demselben Kompromiss. Ein Modell, eine
Entscheidung, ob der Inhalt aus einem Ref oder einer Datei kommt.

::callout{type="tip" title="Grobe Namen altern besser"}
Ein Versionssegment gehört zu jedem Link, den jemand auf deine Dokumentation setzt.
`v2` überlebt die nächsten vierzig Releases; `2.4.1` ist am Tag von `2.4.2` veraltet.
::

## Wenn Versionen keine Refs sind

Eine Version ist normalerweise ein Checkout. Zwei übliche Formen sind es nicht:

**Dokumentation in Ordnern.** `docs/v1` neben `docs/v2` in einem Repository, ohne
Tags. Jede Quelle benennt ihre Version:

```ts [app/app.config.ts]
sources: [
  { path: 'docs/v2', version: 'v2' },
  { path: 'docs/v1', version: 'v1', status: 'deprecated' }
]
```

**Eine API in Dateien.** `openapi/v1.yaml` neben `openapi/v2.yaml` ist eine übliche
Form der API-Pflege. Die Versionen gehören zum *Abschnitt*, nicht zur Quelle:

```ts [app/app.config.ts]
generated: [
  {
    type: 'openapi',
    label: 'API',
    path: 'openapi/v2.yaml',
    versions: [
      { version: 'v2', path: 'openapi/v2.yaml' },
      { version: 'v1', path: 'openapi/v1.yaml', status: 'deprecated' }
    ]
  }
]
```

Beide liefern dasselbe wie Refs: ein URL-Segment, einen Eintrag im Umschalter,
das Banner und das Canonical. Der Umschalter bleibt auf das gelesene Artefakt
beschränkt: Auf `/api` bietet er die API-Versionen, auf einer Prosaseite die
Dokumentationsversionen an.

::callout{type="warning" title="Entweder das eine oder das andere"}
Eine Quelle mit `refs` **und** `version` oder ein Abschnitt mit `versions` auf
einer Quelle mit Refs lässt den Build scheitern: Beide beanspruchen dasselbe
URL-Segment. Die vollständige Feldliste steht unter [Quellen](/reference/sources).
::

## Was mit den alten Versionen passiert

Eine Nicht-Standardversion trägt `noindex` und ein `canonical`, das auf dieselbe
Seite in der Standardversion zeigt, und eine `eol`-Version verlässt die Sitemap
vollständig. Das hindert eine Suchmaschine daran, `v0.9.0` anzubieten, wo der
Leser die heutige Dokumentation wollte — siehe
[URLs und Versionen](/concepts/urls-and-versions).

## Checkliste

- [ ] Jeder Tag ist als `{ tag: … }` geschrieben, nicht als bloße Zeichenkette
- [ ] Die Versionsnamen sind so grob wie die Supportlinien des Projekts
- [ ] `defaultRef` benennt die Version, auf der Leser landen sollen
- [ ] Ein Branch in der Liste trägt einen ausdrücklichen `status`
- [ ] Der Umschalter zeigt jede Version, mit einem Abzeichen an den toten
- [ ] Die Seite einer toten Version fehlt in `/sitemap.xml`
- [ ] Wenn Versionen Ordner oder Dateien statt Refs sind, ist genau eines von
      `refs`, `version` einer Quelle und `versions` eines Abschnitts im Einsatz