Быстрый старт
Установите scribe-cms, задайте схему, напишите контент и получите строго типизированные данные всего за пять шагов.
View as MarkdownУстановка
pnpm add scribe-cms zod better-sqlite3
Требования: Node 20+ и Zod v4. Scribe не привязан к конкретным фреймворкам и отлично работает с любым стеком на базе Node. Поскольку better-sqlite3 является нативным модулем, его следует исключить из сборки (подробности есть на странице runtime API).
1. Создайте scribe.config.ts
Поместите этот файл в корень вашего проекта:
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: ".", // relative to this file (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 и defineContentType сохраняют литеральные типы. Именно благодаря им методы вроде scribe.blog и related(doc, "author") в дальнейшем получают полную типизацию.
2. Напишите контент
content/
blog/
hello-world.mdx
authors/
jane.mdx
---
title: "Hello, world"
description: "A first post that says hello to the world, at length, because the schema demands fifty characters."
author: jane
publishedAt: "2026-01-15"
---
The body is MDX. **Markdown** and components both work.
Имя файла (hello-world) выступает в роли слага для английской версии. Поле publishedAt встроено в систему и доступно для каждого типа (см. модель контента).
3. Валидация
После выполнения pnpm install утилита scribe будет доступна в вашем PATH (так же, как next):
pnpm scribe validate
pnpm scribe status
Добавьте проверку перед запуском сборки:
{
"scripts": {
"build": "scribe validate && <your framework build>"
}
}
4. Чтение контента
import { createScribe } from "scribe-cms/runtime";
import config from "./scribe.config";
const scribe = createScribe(config);
const posts = scribe.blog.list(); // BlogDoc[], newest first
const { document } = scribe.blog.resolve("hello-world", "fr");
const author = scribe.blog.related(document!, "author"); // AuthorDoc, non-null
Типы для document.frontmatter берутся напрямую из вашей схемы Zod. Полное описание возможностей доступно в разделе runtime API.
5. Перевод
export GEMINI_API_KEY=... # or put it in .env
npx scribe translate --locale fr
Scribe автоматически находит все отсутствующие или устаревшие французские версии страниц. Система переводит поля с пометкой field.translatable() и сохраняет результат в базе .scribe/store.sqlite. Обязательно добавьте эту папку в коммит и ни в коем случае не вносите .scribe/ в файл .gitignore. Подробности описаны в разделе перевод.