Eine duxt-Seite ist eine Nuxt-Anwendung. Alles, was Nuxt ausführt, führt sie
aus.

## Schritte

:::steps
1. **Bevorzuge statisch.** `nuxt generate` erzeugt einen Ordner HTML — kein
   Server, keine Laufzeitkosten, jede Seite am Edge zwischengespeichert. Für
   Dokumentation ist das die richtige Vorgabe.

   ::package-managers{command="run generate"}
   ::

   `nuxt build` erzeugt einen Node-Server, den du nur brauchst, wenn eine Seite
   auf eine Anfrage reagieren muss.

2. **Gib dem Build, was er braucht.** Node 24 (die Datenbank wird über
   `node:sqlite` gelesen, ein nativer Treiber wird also nicht installiert),
   Netzzugang zu jeder entfernten Quelle und ein Token für die privaten.

3. **Setze den Ursprung.** `NUXT_PUBLIC_I18N_BASE_URL` oder `i18n.baseUrl` in
   der Konfiguration. Ohne ihn fallen `hreflang`, `canonical`, die Sitemap und
   die Social Cards auf relative Ausgabe zurück.

4. **Setze ein OG-Bild-Geheimnis, wenn du mehr als eine Instanz ausrollst.**
   `NUXT_OG_IMAGE_SECRET`, einmal erzeugt. Ohne es signiert jeder Build die
   Bild-URLs mit einem eigenen Geheimnis, und eine von einer Instanz signierte
   Card wird von der nächsten abgelehnt.

5. **Plane einen erneuten Build.** Eine Seite, die ein anderes Repository liest,
   nimmt dessen Änderungen auf, wenn sie baut, nicht wenn sie gepusht werden.

:::

## Warum es keine Auffrischung zur Laufzeit gibt

Content lädt ein entferntes Repository zur Build-Zeit herunter und übersetzt es
in die Datenbank, die der Build ausliefert. Das zur Laufzeit aufzufrischen
hieße, die Datenbank in einem laufenden Server neu zu bauen — Content bietet
dafür keinen unterstützten Weg, und der einzige verfügbare ist dieselbe
Client-Datenbank, die die Suche liest. Ein geplanter Neubau, oder einer, der vom
Quell-Repository ausgelöst wird, hält das Deployment unveränderlich und die
Inhalte reproduzierbar.

## Wenn ein Build `database is locked` meldet

Content hält seinen Parse-Cache in `.data/content/contents.sqlite`, und ein
Build, den der Kernel oder ein `Ctrl-C` zurückgelassen hat, kann ihn weiterhin
offen halten. Jeder folgende Build scheitert dann mit `database is locked` —
einer Meldung, die weder die Datei noch den Prozess nennt.

duxt versetzt diese Datenbank in den [WAL-Modus](https://www.sqlite.org/wal.html),
bevor Content sie öffnet; das lässt Leser und Schreiber koexistieren und
beseitigt den Alltagsfall vollständig. Was es nicht beseitigen kann, ist ein
zweiter, noch laufender Prozess:

```bash
pgrep -af 'nuxt (build|dev|generate)'   # der verwaiste Prozess, falls vorhanden
kill <pid>
```

Taucht nichts auf und bleibt der Fehler, lösche `.data/content/` — es ist ein
Cache, und der nächste Build baut ihn aus den Quellen neu auf.

## Was die Seite außer Seiten ausliefert

`/llms.txt`, `/llms-full.txt`, den `.md`-Quelltext jeder Seite, `/mcp`,
`/sitemap.xml`, `/robots.txt` und — einmal konfiguriert — `/rss.xml`. Die
vollständige Liste mit ihren Einschränkungen steht in der
[Endpunkt-Referenz](/reference/endpoints).

## Checkliste

- [ ] `nuxt generate` läuft ohne Fehler des Validators durch
- [ ] Der Ursprung ist im Deployment gesetzt, nicht nur lokal
- [ ] `/sitemap.xml` listet absolute URLs auf der echten Domain
- [ ] Ein Neubau ist geplant oder wird von jedem Quell-Repository ausgelöst
- [ ] `NUXT_OG_IMAGE_SECRET` ist gesetzt, wenn mehr als eine Instanz die Seite
      ausliefert