Scribe

快速开始

只需五步:安装 scribe-cms、定义 schema、编写内容,并读取带有完整类型提示的数据。

View as Markdown

安装

pnpm add scribe-cms zod better-sqlite3

环境要求:Node 20+ 及 Zod v4。Scribe 框架无关,能够完美适配任意基于 Node 的技术栈。better-sqlite3 是原生模块,因此请确保将其排除在打包工具的构建范围之外(详见 运行时 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,
    }),
  ],
});

defineConfigdefineContentType 是保留字面量类型的标识函数,正是它们让后续调用的 scribe.blogrelated(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"
---

正文部分为 MDX 格式。**Markdown** 语法及自定义组件均可在此正常使用。

文件名(hello-world)即为英文 slug。publishedAt 是适用于所有类型的内置字段之一,详情请参阅 内容模型

3. 校验

执行 pnpm install 后,scribe CLI 将自动添加至系统的 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 schema 自动推导类型。有关完整 API 的更多信息,请查阅 运行时 API

5. 翻译

export GEMINI_API_KEY=...   # or put it in .env
npx scribe translate --locale fr

Scribe 会自动找出所有缺失或已过期的法语页面,并翻译由 field.translatable() 标记的字段,最后将结果存入 .scribe/store.sqlite务必将该目录提交至版本控制系统,切勿将 .scribe/ 添加至 .gitignore 中。详细说明请查阅 翻译指南

快速开始 · Scribe