Erste Schritte
Installiere scribe-cms, definiere ein Schema, verfasse Inhalte und lies sie in fünf einfachen Schritten wieder typsicher aus.
View as MarkdownInstallieren
pnpm add scribe-cms zod better-sqlite3
Voraussetzungen: Node 20+, Zod v4. Scribe ist framework-unabhängig und funktioniert mit jedem Node-basierten Stack. better-sqlite3 ist ein natives Modul und sollte in deinem Bundler als extern konfiguriert werden (siehe Seite Runtime API).
1. scribe.config.ts erstellen
Lege die Datei im Root-Verzeichnis deines Projekts ab:
import { z } from "zod";
import { defineConfig, defineContentType, field } from "scribe-cms";
const blogSchema = z.object({
title: field.translatable(z.string().min(1)),
description: field.translatable(z.string().min(50).max(250)),
author: field.relation("author"),
tags: field.structural(z.array(z.string()).default([])),
});
const authorSchema = z.object({
name: field.structural(z.string().min(1)),
});
export default defineConfig({
rootDir: ".", // relativ zu dieser Datei (CLI) / process.cwd() (Runtime)
locales: ["en", "fr", "de"],
types: [
defineContentType({
id: "blog",
path: "/blog/{slug}",
schema: blogSchema,
slugStrategy: "localized",
orderBy: "-publishedAt",
}),
defineContentType({
id: "author",
contentDir: "authors",
schema: authorSchema,
}),
],
});
defineConfig und defineContentType sind Identitätsfunktionen, die literale Typen erhalten. Sie sorgen dafür, dass später Aufrufe wie scribe.blog und related(doc, "author") vollständig typsicher sind.
2. Inhalte schreiben
content/
blog/
hello-world.mdx
authors/
jane.mdx
---
title: "Hallo Welt"
description: "Ein erster Beitrag, der die Welt ausführlich begrüßt, weil das Schema fünfzig Zeichen verlangt."
author: jane
publishedAt: "2026-01-15"
---
Der Textkörper besteht aus MDX. Sowohl **Markdown** als auch Komponenten funktionieren einwandfrei.
Der Dateiname (hello-world) ist der englische Slug. publishedAt ist eines der integrierten Felder, die für jeden Typ verfügbar sind; siehe Content-Modell.
3. Validieren
Nach einem pnpm install steht dir die scribe CLI über deinen PATH zur Verfügung (genau wie next):
pnpm scribe validate
pnpm scribe status
Schalte den Befehl vor deinen Build-Prozess:
{
"scripts": {
"build": "scribe validate && <dein-framework-build>"
}
}
4. Inhalte auslesen
import { createScribe } from "scribe-cms/runtime";
import config from "./scribe.config";
const scribe = createScribe(config);
const posts = scribe.blog.list(); // BlogDoc[], neueste zuerst
const { document } = scribe.blog.resolve("hello-world", "fr");
const author = scribe.blog.related(document!, "author"); // AuthorDoc, non-null
Die Typisierung für document.frontmatter wird direkt aus deinem Zod-Schema abgeleitet. Den kompletten Funktionsumfang findest du unter Runtime API.
5. Übersetzen
export GEMINI_API_KEY=... # oder trage es in die .env ein
npx scribe translate --locale fr
Scribe spürt jede französische Seite auf, die fehlt oder veraltet ist, übersetzt alle mit field.translatable() markierten Felder und speichert das Ergebnis in .scribe/store.sqlite. Commite dieses Verzeichnis; setze .scribe/ niemals auf die .gitignore. Weitere Details unter Übersetzung.