Blume 按照发布本身的运作方式来管理文档版本:最新文档位于内容根目录,使用干净、无前缀的 URL;每个历史版本都是各自文件夹中的一份冻结快照。发布时切出一份快照,Blume 就会为你接好版本切换器、“旧版本”提示、搜索范围、SEO 以及面向 agent 的接口。它是可选的:没有 versions 块,一切保持原样。
启用#
添加一个 versions 块,声明当前文档以及任何已归档的快照:
versions: {
current: { label: "v2.0", badge: "Latest" },
archived: [
{ id: "v1.0" },
{ id: "v0.9", label: "0.9 (legacy)" },
],
}
current 用来在切换器中标注那棵无前缀的目录树(可搭配一个可选的 badge)。每个归档条目的 id 既是快照的目录名,也是它的 URL 片段——id 必须以字母开头(v1.0,而不是 1.0),这样才永远不会与数字排序前缀冲突。归档版本按从新到旧排列;这个顺序就是切换器里的顺序。
切出一个版本#
发布时,用一条命令冻结当前文档:
blume version v1.0
它会把你的内容目录复制到 docs/v1.0/(已有的快照不参与复制),重写副本内部以根路径开头的链接,让它们留在该快照之内(/guides/x 变成 /v1.0/guides/x,围栏代码和行内代码不受影响),并在 blume.config.ts 中注册这个 id——首次切出版本时会自行补上 versions 块,并把线上文档标记为 “Latest”——如果你的配置写法它不会改动,则改为给出警告并打印出可供粘贴的条目。指向不属于被复制目录树的页面链接——生成的 API 参考、像更新日志这样的远程源——仍会指向线上页面,因为快照里并没有它们的副本。不带 id 运行 blume version 可列出已配置的版本。
像对待其他内容一样审阅并提交这个新目录。重启 blume dev 即可识别它。
docs/
index.mdx -> / (最新)
guides/quickstart.mdx -> /guides/quickstart
v1.0/
index.mdx -> /v1.0 (冻结)
guides/quickstart.mdx -> /v1.0/guides/quickstart
归档意味着冻结。 后续的修改属于线上目录树;快照就是当时的文档。Blume 正是依赖这一点:快照保留各自的文件夹元数据和翻译,blume translate 永远不会重新翻译它们,而配置中的显式侧边栏只对当前文档生效——快照的侧边栏永远来自它自己的文件。
切换器与提示条#
配置了版本后,头部会自动长出一个版本下拉菜单。切换时,若目标版本中存在同一页面就落到它,否则落到该版本的根(设置 switcher.redirect: "root" 可始终落到根)。如果你在 navigation.selectors 中声明了自己的 kind: "version" 选择器,它会取代自动生成的那个。
每个归档页面还会显示一条不可关闭的提示,带有指向该页线上对应页面的“Go to latest”链接。可以按版本定制或关闭它:
versions: {
current: { label: "v2.0" },
archived: [
{ id: "v1.0", banner: "These docs cover the 1.x SDK." },
{ id: "v0.9", banner: false },
],
}
SEO#
旧文档是搜索引擎最爱踩的坑:过时的页面排在现行的前面,或者两者互相争位。Blume 默认采用 SEO 指南推荐、而其它文档框架都不自动做的方案——归档页面仍可被索引,但会把最新对应页面声明为自己的 canonical,于是线上页面是权威版本,而仅存在于某个版本中的内容(在最新文档里已不存在的页面)则用自身 canonical 保持可被找到。
你可以按版本选择不同的处理方式:
versions: {
current: { label: "v2.0" },
archived: [
{ id: "v1.0" }, // canonical → 最新(默认)
{ id: "v0.9", canonical: "self" }, // 每个页面都是权威
{ id: "v0.8", noindex: true }, // 完全不收录
],
}
站点地图与此保持一致:canonical 指向线上对应页面的归档页面会被排除,noindex 版本被整体排除,仅存在于某个版本的页面则继续列出。页面自身的 seo.canonical frontmatter 始终优先。
搜索#
搜索对话框会把结果限定在当前浏览的版本上,语言切换器旁边还有一个“All versions”开关(按读者记住)。跨版本命中的结果会在结果行里标出它所属的版本。Orama(默认)、FlexSearch、Algolia 和 Typesense 都遵守这一范围限定——托管记录带有 version 分面,当前文档以 "current" 上传。Pagefind、Orama Cloud 和 Mixedbread 不按版本限定:它们的结果横跨所有版本,对话框也不会显示那个开关。
Agent 接口#
面向 agent 的接口是感知版本的——这是其它文档框架都做不到的:
- MCP 的
search_docs和list_pages工具默认检索当前文档,并接受version:一个归档 id("v1.0")或"all"。按需调用get_navigation可返回某个归档快照的目录树。 llms.txt会把归档版本排在当前文档之后,用该版本的label或id加上(archived)作为标注——上面那个{ id: "v1.0" }对应v1.0 (archived)——这样读取索引的 agent 就知道哪些文档已冻结。llms-full.txt只包含当前版本——这份平铺的转储不会把同一页面的冻结副本交叉混排进来。- 助手会以读者正在浏览的版本为依据来作答——当前文档,除非读者停在归档页面上——这样页面的冻结副本不会把正在读的那一份挤掉。
- 原始 Markdown 镜像(
.mdURL)与其它路由一样,为每个版本的页面都存在。
与 i18n 一起使用#
版本管理可以与国际化组合使用。在磁盘上版本文件夹位于最外层——快照自然包含它自己的语言文件夹;而在 URL 里语言仍位于最外层,与站点其余部分保持一致:
docs/
guides/x.mdx -> /guides/x
fr/guides/x.mdx -> /fr/guides/x
v1.0/
guides/x.mdx -> /v1.0/guides/x
fr/guides/x.mdx -> /fr/v1.0/guides/x
语言回退在每个版本内部各自生效:未翻译的快照页面会在本地化 URL 上渲染回退语言的内容,hreflang 备选链接也按版本分组。版本 id 不能与已配置的语言代码冲突——Blume 会直接拒绝这种配置。
不参与版本管理的内容#
版本管理覆盖的是文档内容目录树。博客、更新日志、从 OpenAPI 规范生成的 API 参考以及自定义页面始终是当前版本。还有两点行为值得知道:头部标签页是针对当前文档定义的,因此在归档目录树内部侧边栏渲染时不受标签页限定;而大型站点要注意每个快照都是一份完整副本——内容、搜索索引条目和导航数据都会随版本增长。