Git-ориентированная CMS для мультиязычных MDX-сайтов
Английский контент хранится в MDX-файлах вашего репозитория. ИИ-переводы — рядом, в файле SQLite. Zod проверяет и то и другое, а типизированный рантайм считывает всё на этапе сборки. Никакого сервера CMS, никаких сетевых запросов в реальном времени.
pnpm add scribe-cms zod better-sqlite3Как это работает
- 1
Задайте схему
Типы контента — это схемы Zod. Укажите, какие поля нужно переводить, какие остаются только на английском и как документы ссылаются друг на друга.
// scribe.config.ts defineContentType({ id: "blog", path: "/blog/{slug}", slugStrategy: "localized", schema: z.object({ title: field.translatable(z.string().min(1)), description: field.translatable(z.string().min(50)), author: field.relation("author"), heroImage: field.structural(z.string().optional()), }), }); - 2
Напишите контент
Один MDX-файл на документ, всё коммитится в репозиторий. Имя файла становится английским слагом, а frontmatter проверяется по схеме.
--- title: "Hello, world" description: "A first post that says hello to the world." author: jane publishedAt: "2026-01-15" --- The body is MDX. **Markdown** and <Components /> both work. - 3
Переводите только то, что изменилось
Текст для перевода хешируется, поэтому в Gemini отправляются только новые или изменённые страницы (через Batch API, за полцены). Промпт настроен на транскреацию, чтобы текст звучал естественно для носителей. Результат парсится как MDX перед сохранением: если ИИ ошибся, упадёт скрипт, а не сайт.
export GEMINI_API_KEY=... npx scribe translate --locale fr de --dry-run # show the worklist npx scribe translate --locale fr de # translate, validate, store git add .scribe/store.sqlite # translations live in git - 4
Читайте с полной типизацией
Рантайм выводит типы документов из вашего конфига. Списки, выборки, связи, альтернативные ссылки hreflang и элементы sitemap возвращаются со строгой типизацией.
const scribe = createScribe(config); const posts = scribe.blog.list("fr"); // BlogDoc[] const { document } = scribe.blog.resolve(slug, "fr"); // EN fallback built in const author = scribe.blog.related(document!, "author"); // AuthorDoc const hreflang = scribe.blog.alternates(document!);
Что вы получаете
Инкрементальный перевод
Переводы привязаны к хешу английского исходника. Отредактировали абзац — переводится только этот документ. Оценить стоимость можно заранее в режиме dry-run.
Текст, как от носителя
Промпт создан для транскреации: голос опытного копирайтера, который адаптирует идиомы, а не переводит слово в слово.
Валидация перед сохранением
Каждый перевод парсится как MDX и снова проверяется по схеме Zod перед записью. Ошибки модели ломают команду обновления, но не продакшен.
Сквозная типизация
Схемы Zod, автоматический вывод типов документов, никакой генерации кода. Связанные объекты возвращаются разыменованными и полностью типизированными.
Встроенные токены
Ссылки, ресурсы и непереводимые строки встраиваются прямо в текст. Изменили токен — он мгновенно обновился во всех локалях без повторного перевода.
Всё для SEO
Теги hreflang, sitemap с x-default, канонические ссылки, noindex, правила редиректов в JSON и цепочки фолбеков для локалей.
Всё хранится в git
MDX-файлы плюс одна база SQLite в репозитории. Снапшоты помнят, из какого исходника сделан перевод, а scribe history показывает всю историю изменений.
Никакого сервера
Всё читается с диска на этапе сборки. Работает с Next.js, Astro и любым Node-стеком. Локальная студия добавляет навигацию, поиск и наглядную статистику переводов.
Создано для ИИ
Агенты читают и правят MDX теми же инструментами, что и код, а каждое изменение — это понятный диф, который вы ревьюите. Никакого API между моделью и текстом.
Открытая разработка
scribe-cms распространяется по лицензии MIT и разрабатывается на GitHub. Этот сайт работает на нём. Каждая страница здесь — это контент scribe с базой SQLite для десяти локалей. Изучайте код, открывайте issue или присылайте pull request.