内容模型
文件、frontmatter、内置字段、重定向以及 scribe validate 的检查项。
View as Markdown文件
一个文档等于该类型文件夹中的一个 .mdx(或 .md)文件:
content/
blog/
hello-world.mdx → slug 为 "hello-world"
_redirects.json → 该类型的重定向规则(可选)
authors/
jane.mdx → slug 为 "jane"
- 文件名即为英语版本的 slug。Slug 采用小写,并且使用连字符分隔(kebab-case)。
- 磁盘上只存在英语文件;其他语言版本的数据保存在 SQLite 数据库中。
- 如果文件名以
_或大写字母开头(例如PUBLISHING.md),系统会忽略它们,因此你可以把笔记跟内容文件放在一起。
Frontmatter
Frontmatter 使用 YAML 编写,并根据该类型的 Zod schema 进行验证:
---
title: "Hello, world"
description: "满足 schema 要求的长度足够的描述。"
author: jane
publishedAt: "2026-01-15"
updatedAt: "2026-02-01"
---
正文使用 MDX 格式。
Schema 验证遵循你的 Zod schema:对于普通的 z.object,未知的键会被静默丢弃;如果你希望字段名称拼写错误时能触发验证失败,请使用 .strict()。
内置的 frontmatter 字段
以下字段在每个内容类型中都可用,无需在 schema 中声明。这些字段会在你的 schema 运行前从 frontmatter 中提取,因此在 Zod schema 中声明它们没有任何作用:
| 字段 | 类型 | 说明 |
|---|---|---|
publishedAt | ISO 日期 | 发布日期。 |
updatedAt | ISO 日期 | 最后一次重要更新的日期。默认与 publishedAt 相同。用于生成站点地图的 lastModified。 |
noindex | 布尔值 | 从站点地图中排除该页面;你可以在页面中将其作为 robots meta 标签输出。 |
canonicalPath | 字符串 | 手动覆盖规范(canonical)URL 路径。 |
多语言文档会从它们的英语源文档继承 publishedAt、updatedAt、noindex 和 canonicalPath;翻译人员无法更改这些字段。
每一个加载的文档都会附带 slug、enSlug(英语源文档的 slug,在英语文档中与 slug 相同)、locale、frontmatter 以及 content 属性。
无正文(Bodyless)类型
那些仅供引用的集合(例如 model 或 category 类型,其 schema 完全是结构化的数据)通常根本没有 MDX 正文。你可以在该类型上声明 body: false 来明确指出这一点:
defineContentType({
id: "model",
contentDir: "models",
schema: modelSchema,
body: false, // 条目仅包含 frontmatter
});
默认值为 body: true,所以这是完全向后兼容的。对于 body: false 的类型,包含除空白字符以外的任何正文内容都会导致验证错误。加载器会跳过 MDX 解析,并且静态导出不会输出正文。如果一个无正文类型同时具有零个可翻译字段,那么它将不会进入任何翻译流程(不会产生未翻译或内容已旧的干扰信息);如果无正文类型仍包含可翻译字段,它将带着仅有 frontmatter 的有效负载保留在待办事项列表中。关于可翻译性的规则,请参见 翻译。
超越 Frontmatter
MDX 正文不仅能用于编写普通的纯文本:
- 行内标记(Inline tokens) 可以将链接、资源 URL 以及不可翻译的字面量直接嵌入正文中,这些标记在读取时会根据具体语言进行解析。
- 通过
field.asset()声明的 资源(Assets) 会在磁盘上进行验证,并在加载时解析为公开 URL。
重定向:_redirects.json
在每个内容类型文件夹中,你可以添加一个可选的 _redirects.json 文件来声明 slug 的变更和已停用的文档。删除源 MDX 文件后,重定向规则依然生效;被翻译的源 slug 会自动通过 SQLite 展开。
{
"redirects": [
{ "from": "hello-world", "toSlug": "hello-scribe" },
{ "from": ["old-a", "old-b"], "toSlug": "hello-scribe" },
{ "from": "moved-post", "toType": "glossary", "toSlug": "virtual-try-on" },
{ "from": "retired-page", "toUrl": "/pricing" },
{ "from": "retired-ext", "toUrl": "https://example.com/app" }
]
}
共有三种重定向类型(每个条目只能有一个目标):
| 类型 | 字段 | 说明 |
|---|---|---|
| 同类型 | toSlug | 相同内容类型下的目标英文 slug。URL 根据该类型的 path 生成,并随语言本地化。 |
| 跨类型 | toType + toSlug | 另一个可路由内容类型(必须有 path)下的目标英文 slug。 |
| 任意位置 | toUrl | 基于站点根目录的相对路径,或外部的绝对 URL。不同语言环境的目标相同。 |
from:仅限英文 slug。翻译的源 slug 会从 SQLite 解析。- 可选字段
permanent(默认为true)。
要停用或重命名文档:请在 _redirects.json 中添加相应的条目,删除(或重命名)源 MDX 文件,然后运行 scribe validate 并重新构建项目。重定向规则由 buildAllContentRedirects() 输出,供你的代理服务器或框架配置使用。
验证
scribe validate
针对每个英文文件执行以下检查:schema 解析、内置字段的格式、你编写的 crossValidate 钩子,以及对正文进行 MDX 编译。无论是英文原文还是存储的翻译内容,如果正文无法作为 MDX 成功解析,都会产生阻断构建的错误。
在整个项目级别,它还会检查以下内容:关系完整性(缺失必填关系 = 错误,缺失可选关系 = 警告)、_redirects.json 规则(目标是否有效、源是否重复、是否存在重定向链)、本地化 slug 后缀规则、声明的资源字段(文件是否存在、formats、maxKB)、行内正文标记(格式错误的 span、缺失关系、对不可路由类型的 :href 引用、缺失的 vars 键、缺失的资源文件)、声明为 body: false 但仍带有正文内容的类型、当设置了资源目录时缺失的图片资源,以及翻译存储库是否存在。
如果发现任何错误,退出状态码将非零。请在构建项目前运行它:
{
"scripts": {
"build": "scribe validate && <your framework build>"
}
}