Scribe

Konfiguration

Alle Optionen für scribe.config.ts: Projekteinstellungen, Inhaltstypen, Feldmarkierungen und lokales Routing.

View as Markdown

Alles befindet sich in einer einzigen Datei, scribe.config.ts, die defineConfig({...}) exportiert. Sowohl die Laufzeitumgebung (createScribe) als auch die CLI (welche scribe.config.ts im Arbeitsverzeichnis sucht) lesen dieselbe Datei.

Project options

export default defineConfig({
  rootDir: ".",
  contentDir: "content",             // default
  store: ".scribe/store.sqlite",     // default
  assetsDir: "public",               // optional
  locales: ["en", "fr", "de"],
  defaultLocale: "en",               // default
  localeRouting: { strategy: "path-prefix", prefixDefaultLocale: false },
  localeFallbacks: true,             // default
  localePresets: { active: ["fr"] },
  translate: { /* see the translation page */ },
  types: [ /* defineContentType(...) */ ],
});
OptionDefaultDescription
rootDir(Erforderlich)Projektstammverzeichnis. Pfad relativ angeben (meistens "."): Die CLI löst ihn relativ zum Verzeichnis der Konfigurationsdatei auf, createScribe relativ zu process.cwd(). Den Pfad nicht aus import.meta.url generieren. Bundler binden diesen Pfad zur Build-Zeit direkt ein, was auf Serverless-Plattformen wie Vercel zu Fehlern führt.
contentDir"content"Verzeichnis, das für jeden Inhaltstyp einen eigenen Ordner enthält.
store".scribe/store.sqlite"SQLite-Datenbank für Übersetzungen. Unbedingt committen, .scribe/ nicht in die gitignore aufnehmen.
assetsDir(Leer)Stammverzeichnis für statische Assets (beispielsweise "public"). Wenn gesetzt, warnt scribe validate vor Bildpfaden im Frontmatter oder Text, die physisch nicht existieren.
locales(Erforderlich)Alle unterstützten Sprachen (Locales), inklusive der Standardsprache.
defaultLocale"en"Die primäre Quellsprache. Muss in locales enthalten sein.
localeRoutingpath-prefix, unprefixed defaultLegt fest, wie Sprachkürzel in generierten URLs erscheinen. Bei path-prefix wird die Sprache vorangestellt (die Standardsprache wird weggelassen, sofern prefixDefaultLocale nicht auf true steht). Bei search-param wird ?param=locale für alle abweichenden Sprachen angehängt.
localeFallbackstrueLeitet Fallback-Ketten automatisch aus den Sprach-Tags ab. Eine regionale Variante ohne eigene Übersetzung erhält so zunächst die Übersetzung der Hauptsprache (so fällt pt-BR auf pt zurück), bevor auf die Standardsprache zurückgegriffen wird. Zum Deaktivieren auf false setzen. Weitere Details unter Fallback-Ketten für Sprachen.
localePresets(Leer)Benannte Sprachgruppen für den Befehl scribe translate --preset name.
translate(Leer)Projektweite Standardwerte für Übersetzungen (Übersetzung).
types(Erforderlich)Definitionen der Inhaltstypen.

Konfigurationen werden im Vorfeld validiert. Eine unbekannte defaultLocale, doppelte Typ-IDs oder eine fehlerhafte path-Vorlage werfen sofort einen Fehler mit einer eindeutigen Meldung.

Content type options

defineContentType({
  id: "blog",
  schema: blogSchema,
  path: "/blog/{slug}",
  contentDir: "blog",          // default: the id
  slugStrategy: "localized",   // default: "fixed"
  indexFallback: "en",         // default: "en" if path is set, else "none"
  orderBy: "-publishedAt",     // default: "slug"
  label: "Blog",               // default: capitalized id (studio UI only)
  crossValidate: (data, ctx) => [],
  translate: { /* per-type overrides */ },
})
OptionDescription
idEindeutige ID. Dient als typisierter Zugriff (scribe.blog) und als standardmäßiges contentDir.
schemaZod-Objektschema für das Frontmatter mit den unten stehenden Feldmarkierungen.
pathURL-Vorlage mit genau einem {slug} (etwa /blog/{slug}). Bei reinen Referenztypen (wie Autoren oder Kategorien), die keine eigenen Seiten haben, einfach weglassen.
contentDirOrdner innerhalb des projektweiten contentDir, der die .mdx-Dateien für diesen Typ enthält.
slugStrategy"fixed" bedeutet, dass jede Sprache den englischen Slug verwendet. Bei "localized" erstellt der Übersetzer einen individuellen Slug pro Sprache (/de/blog/hallo-welt).
indexFallbackBestimmt die Rückgabe von resolve(), wenn für eine Sprache keine Übersetzung vorliegt. "en" liefert das englische Dokument (mit actualLocale: "en"), "none" gibt nichts zurück.
orderByStandard-Sortierung für list(). Mögliche Werte sind "slug", "publishedAt", "-publishedAt", "updatedAt", "-updatedAt" oder eine Vergleichsfunktion (a, b) => number für vollständig typisierte Dokumente.
crossValidateZusätzliche Validierung durch scribe validate. Erhält das geparste und typisierte Frontmatter. Als Rückgabe wird { field, message, level }[] erwartet.
translateIndividuelle Übersetzungs-Prompts, Regeln oder Modelle pro Typ (Übersetzung).

Field markers

Jedes Schema-Feld gehört zu einer von drei Kategorien. Unmarkierte Felder werden standardmäßig als strukturell behandelt.

import { field } from "scribe-cms";

const schema = z.object({
  // Sent to the translator, stored per locale:
  title: field.translatable(z.string().min(1)),

  // English-only; copied from the EN document into every locale:
  heroImage: field.structural(z.string().optional()),

  // English slug reference(s) to another content type:
  author: field.relation("author"),
  relatedPosts: field.relation("blog", { multiple: true, max: 4, optional: true }),
});

Übersetzbare Markierungen funktionieren auch bei Feldern, die in einfachen Arrays oder Objekten verschachtelt sind (etwa sections.*.title). Wichtig ist nur, das umgebende Array nicht mit field.structural zu umschließen, da sonst der gesamte Teilbaum nur auf Englisch verfügbar bleibt.

field.relation(typeId, options?)

OptionDefaultDescription
multiplefalseDas Feld ist ein Array von Slugs.
optionalfalseDas Feld darf weggelassen werden. related() gibt dann null zurück (bei Einzelwerten) oder überspringt fehlende Einträge (bei mehreren Werten).
min / max(Leer)Begrenzungen für die Anzahl der Einträge (nur bei multiple: true).

Einschränkungen gehören in das Optionen-Objekt, nicht in verkettete Zod-Methoden. Eine Verkettung (wie .max(8) oder .optional()) klont das Schema und würde dabei die Metadaten der Relation entfernen.

Relationen speichern grundsätzlich die englischen Slugs und werden von scribe validate geprüft. Eine fehlende Referenz bei einer Pflichtrelation führt zu einem Fehler, der den Build-Prozess stoppt. Bei einer optionalen Relation wird lediglich eine Warnung ausgegeben. Zur Laufzeit werden sie mit related() aufgelöst (siehe Laufzeit-API).

Locale fallback chains

Standardmäßig wird für eine regionale Sprache ohne eigene Übersetzung die Basissprache ausgeliefert, bevor auf die Standardsprache zurückgegriffen wird. Jede Sprache testet nacheinander die kürzeren Präfixe des eigenen Tags, die ebenfalls in locales definiert sind. So fällt fr-CA auf fr zurück und zh-Hant-TW probiert erst zh-Hant und dann zh. Dies lässt sich mit localeFallbacks: false deaktivieren. Die Standardsprache ist niemals Teil einer solchen Kette. Sie bleibt der finale Fallback, welcher über den indexFallback des Typs geregelt wird.

Diese Fallbacks gelten für resolve() (die tatsächlich ausgelieferte Sprache steht in actualLocale, und Slug-Weiterleitungen nutzen den Slug der Fallback-Sprache) sowie für staticParams() (vorab gerenderte Slugs entsprechen dem, was resolve() liefert). Für get(), list(), translation(), alternates() oder die Sitemap gelten sie ganz bewusst nicht. Diese erfordern weiterhin einen exakten Treffer.

Typed client types

Für anwendungsseitige Typ-Aliase lässt sich alles direkt aus der Konfiguration ableiten:

import type { ScribeClient, ScribeDocs } from "scribe-cms/runtime";
import config from "./scribe.config";

type MyScribe = ScribeClient<typeof config>;
type BlogDoc = ScribeDocs<typeof config>["blog"];
Konfiguration · Scribe