功能与运行时行为
Doctrine 在开发 SSR、生产预渲染和浏览器 hydration 中使用同一套路由模型与 React 外壳。两个 命令的生命周期不同,但渲染的是同一种页面模型。
MDX 优先开发服务器
doctrine dev 会创建自定义 Vite 服务器。每次收到文档请求时,它加载当前 server entry、查找
归一化路由、import MDX 模块、渲染 HTML,再交给 Vite 转换后返回。
Watcher 处理两类相关源码:
- MDX 的新增、修改与删除会更新
@amamo/mdx记录。 meta.ts和meta.<locale>.ts变化会让导航与图标 virtual module 失效,并触发 full reload。
Serve 模式允许相关文件依次保存时出现短暂导航不一致。新页面只有在最近的导航文件引用后才会 进入路由列表;生产构建则执行严格校验。
静态网站生成
doctrine build 会执行完整流水线:
- 校验输出安全性、配置、locale 和导航。
- 用 Vite 构建浏览器与 SSR environment。
- Import SSR entry 并列出文档路由。
- 预渲染每条路由和共享的
404.html。 - 启用页面操作时,输出与路由对应的原始 MDX 源码。
- 移除 Vite 私有 manifest。
- 根据最终输出目录生成 Pagefind 索引。
每篇文档页面都包含 <html lang>、title、description、canonical URL、匹配的语言 alternate 和
共享资源。存在默认 locale 翻译时,Doctrine 还会输出 x-default alternate。
路由与导航
内容路径会成为路由 slug:
docs/index.mdx -> /
docs/guide/page.mdx -> /guide/
docs/reference/config.mdx -> /reference/config/
docs/reference/config.zh-CN.mdx -> /zh-CN/reference/config/index.mdx 和 page.mdx 都代表所在目录,因此同一目录、同一 locale 不能同时使用两者。其他
basename 会变成带结尾斜杠的路由。
导航只来自就近元数据。每个条目只能命名直属页面或直属子目录;数组定义准确顺序、页面标题、 分组标题和可选图标。生产构建会拒绝遗漏、重复或不存在的引用。
页面条目也可以指向同目录的 .tsx 文件。Doctrine 只 import 最近语言导航文件明确列出的 TSX,
未列出的文件仍是普通组件,不会被当作页面解析。TSX 页面沿用导航标题和路由,但只放进共享的
顶部导航与页脚,不渲染文档侧栏、正文排版或本页目录。同一 locale 下,MDX 与 TSX 不能使用
相同的页面 basename。
export default {
items: [{ page: 'landing', title: '落地页' }],
}export default function LandingPage() {
return <main>在这里构建任意 React 布局。</main>
}Doctrine 默认的 MDX 链接组件会给根相对链接补上部署 base。外部 https://... 链接在新标签页
打开。注册自定义 a 组件会替换这套行为。
页面操作与原始 Markdown
默认情况下,每个 MDX 正文页都有 Copy Page 操作,其菜单还会提供 View as Markdown。
配置 githubUrl,且能够推导仓库内源码根目录或显式设置 githubSourceRoot 时,还会显示
Open in GitHub。GitHub 操作通过 blob/HEAD 指向当前 locale 的真实源文件,让 GitHub 解析到
仓库默认分支。因此,翻译路由会打开带 locale 后缀的源文件,而不是默认 locale 文档。
Doctrine 在开发环境提供同一份原始源码,并在生产构建中将其写入路由对应的 .md URL:
/ -> /index.md
/index/ -> /index/index.md
/guide/install/ -> /guide/install.md
/zh-CN/guide/install/ -> /zh-CN/guide/install.md额外的 index 段用于避免站点根页与真实的 /index/ 文档争用同一个文件。
这里输出的是原始 MDX,不是从渲染后 HTML 还原的 Markdown,因此可以包含 frontmatter、ESM import、
JavaScript 表达式和 JSX。Copy Page 复制同一份源码,View as Markdown 则打开对应的 .md
URL。
独立 TSX 页面不显示这些操作,也不会生成 .md 源码路由。设置 pageActions: false 可以在整个
站点关闭页面操作和 MDX 源码输出,但不会移除 Header 中独立的 GitHub 链接。
搜索
生产搜索会索引渲染后的 HTML,包括自定义 MDX 组件输出的文字。浏览器只在用户输入查询后加载 Pagefind,短暂等待后最多显示八条结果。⌘K 和 Ctrl+K 都能打开搜索。
开发环境不会写永久索引。第一次搜索请求根据当前 SSR 结果在内存中构建 Pagefind 文件。内容或 导航变化会让缓存失效,下一次搜索请求再重建。
多语言
默认 locale 没有路由前缀,其他 locale 使用编码后的前缀。只有另一个文档具有相同 slug 时, 语言按钮才会显示。
导航和页面元数据都不会跨 locale fallback;语言切换标签缺失时直接显示 locale code。
Doctrine 内置界面文案只区分两组:名称以 zh 开头的 locale 使用中文,其余使用英文。内容、
导航、网站元数据、路由前缀和 <html lang> 仍使用完整的配置 locale。
主题与自定义
主题控件把 light 或 dark 写入 localStorage。Head 中的内联脚本会在页面 body 渲染前应用
已保存选择;首次访问则使用操作系统偏好。
Doctrine 提供预编译界面 CSS,以及 Badge、Callout、Card、CardGrid、CodeBlock、
FileTree、FileTreeFolder、FileTreeFile、InstallTabs、LivePreview、Step、Steps、Tab 和
Tabs。语义化的折叠内容、定义列表、图片说明、键盘输入、重点、引用和表格无需包装组件也会
获得完整样式。配置的 CSS 在默认样式之后加载;自定义组件映射在内置映射之后合并,并由 SSR 和
浏览器 hydration 共用。
内置能力与示例见 MDX 组件。
Tailwind 是可选项。只有文档项目根 package.json 在 dependencies、dev dependencies 或
optional dependencies 中声明 tailwindcss 时,Doctrine 才启用对应 Vite 插件。
部署子路径
siteUrl 的 pathname 会成为 Vite 公开 base。Doctrine 把它应用到资源、默认 MDX 链接、语言
路由、Pagefind 结果、canonical URL 和 404 页资源,但不会嵌套输出目录。
信任边界
静态产物不会让源码失去执行能力。MDX 可以包含 ESM 和 JavaScript 表达式;被导航引用的 TSX
页面、doctrine.config.*、导航模块和自定义组件也都是可执行模块。它们可能在加载配置、打包、
SSR 或 hydration 时运行。只能构建你愿意授予构建机器与部署网站权限的可信源码。
内置 frontmatter schema 只校验可选字符串 description,它不是沙箱。编译器的详细边界见
@amamo/mdx 安全模型。