Frontmatter 字段完整手册
Frontmatter 是 Markdown 文件最开头、由两行 --- 包起来的一段 YAML。它不显示在正文里,但决定页面的标题、URL、摘要、分类、侧边栏、搜索、评论、排序等行为。
本文以当前仓库为准,覆盖文章页、目录页、普通指南页和少量系统页字段。先记住一句话:文章放 docs/posts/,目录页放 docs/catalog/,指南放 docs/writing-guide/;不要让页面靠省略字段去猜测。 当前 autoFrontmatter 配置会跳过已有普通 frontmatter 的文章,所以不要把自动补值当成可靠机制;稳定文章必须显式写关键字段。
1. 先分清页面类型
| 页面类型 | 文件放在哪里 | layout | 必须或推荐显式写的标记 | 访问地址 |
|---|---|---|---|---|
| 普通文章 | docs/posts/<一级分类>/... 或更深层子目录 | 省略,使用 doc | article: true、sidebar: true、pagefind-indexed: true、comment: true | /posts/... |
| 目录页 | docs/catalog/... | page | catalogue: true、path,并关闭侧栏、评论、搜索和文章统计 | /catalog/... |
| 写作指南或工具页 | docs/writing-guide/... | doc(或省略) | 四个开关都写 false,正文保留唯一一个 H1 | /writing-guide/... |
| 首页 | docs/index.md | home | 系统维护,不是文章模板 | / |
| 系统功能页 | docs/@pages/... | 按模板固定 | 只由站点维护者修改 | /categories、/archives 等 |
目录页、指南页和文章页的视觉结构不同。目录页使用 layout: page;写作指南和工具页使用默认文档布局 layout: doc(也可省略),这样 Markdown 会得到标准的正文、表格和代码样式;目录页还需要 Teek 的 catalogue 机制扫描文章目录。
docs/posts/ 下不要创建 index.md 作为分类入口;docs/.vitepress/sidebar.ts 和 docs/.vitepress/search-manifest.ts 都会跳过它。新的分类入口应放在 docs/catalog/,文章只放普通 Markdown 文件。
2. Frontmatter 是什么,YAML 必须怎么写
一个完整的 Markdown 文件结构如下:
---
title: 示例文章
tags:
- VitePress
- Markdown
---
# 示例文章
这里是正文。第一行必须直接是 ---,结尾的 --- 必须单独占一行。两行 --- 之间只能是 YAML;闭合线之后才是 Markdown 正文。
| 规则 | 正确写法 | 错误写法或原因 |
|---|---|---|
| 开场线在第一行 | 第一行从第 1 个字符开始就是 --- | 前面有空格、空行、说明文字,frontmatter 不会被识别 |
| 闭合线单独成行 | --- | 写成 ----、...,或者忘记闭合 |
| 键值使用 ASCII 冒号 | title: 标题 | title:标题 使用了中文冒号,字段不会被识别,且可能造成 YAML 解析错误 |
| 冒号后加空格 | date: 2026-11-07 12:00:00 | date:2026-11-07 不是标准的键值分隔写法 |
| 缩进只用空格 | 两个空格表示一层 | 使用 Tab;YAML 不允许用 Tab 缩进 |
| 布尔值小写 | article: true、comment: false | True、FALSE、是/否 都不要写;项目脚本和阅读习惯都按小写处理 |
| 数组用短横线或方括号 | 多行:- 技术笔记;单行:[技术笔记, 生活随笔] | 把数组写成带中文逗号的一串文本;数组项内有逗号时要用引号 |
| 需要时给字符串加引号 | title: "VitePress: 入门" | 值里有 ASCII 冒号加空格、 #、引号或特殊开头字符时,不加引号可能被 YAML 误解 |
# 是注释符号 | # 这一行是注释 | 想把 # 放进值里时要加引号,例如 title: "使用 # 标签" |
| 不要重复键 | 每个键只出现一次 | 重复 title 容易让后一个值覆盖前一个值,排查困难 |
推荐习惯:
- 字段值尽量短而明确,一行写不完时再使用 YAML 多行字符串。
- 布尔值直接写裸的
true或false,不要再包一层引号。 - 数字型字段直接写数字,例如
sidebarSort: 10,不要写"10"。 - 字段名区分大小写和单复数,例如
categories、pagefind-indexed、inHomePost必须照写,不能改成category或pagefindIndexed。 - 文件名和 slug 推荐使用英文、数字和短横线;中文可以出现在
title和categories中。 - 修改 frontmatter 后至少重新启动一次开发服务;若新增或修改了
catalogue: true,必须重启才能重新扫描目录。
需要多行文本时,使用 YAML 块标量,不要直接写未缩进的下一行:
description: >-
这是一段较长的说明,
换行会折叠成空格。反例:
# 错误:中文冒号不是 YAML 的键值分隔符
title:示例文章
# 错误:冒号后没有空格
# 错误:Tab 缩进
categories:
<Tab>- 技术笔记上面的 <Tab> 表示一个真实的 Tab 字符,不是要照字面输入。
正例:
title: 示例文章
categories:
- 技术笔记3. 最小可发布文章
下面是一篇普通文章可以复制的最小发布模板。正文必须从唯一一个 H1 开始;这里已经显式写出四个常用开关,避免依赖默认值。
---
title: 最小可发布文章
description: 用一句话说明这篇文章解决什么问题。
permalink: /posts/技术笔记/minimal-article
categories:
- 技术笔记
article: true
sidebar: true
pagefind-indexed: true
comment: true
---
# 最小可发布文章
## 背景
说明写作背景。
## 正文
写主要内容。
## 总结
总结结论。tags 不是发布必需项,但推荐写 2 到 5 个真正有检索价值的标签。author 通常不要写,因为 docs/.vitepress/config.ts 已经配置了站点作者 { name: "Baecon", link: "/" }。
4. 省略字段时,系统实际会做什么
本项目另有 docs/.vitepress/article-date.ts 初始化器:在每次启动开发服务器或构建前扫描 docs/posts/,发现文章没有 date 时,读取该 Markdown 文件第一次 Git commit 的作者时间(git log --follow --format=%ai --reverse),写入 YYYY-MM-DD HH:mm:ss。文件尚未提交时没有 Git 创建时间,不会写入;Teek 暂时用文件创建时间兜底,提交后再次启动或构建会写入并保持稳定。
这表示创建时间不是 push 时间,也不是构建时间。正常历史下:
创建时间 = 文件第一次 commit 的作者时间
更新时间 = 文件最近一次 commit 的作者时间如果没有改写历史、使用完整克隆,更新时间不会早于创建时间;如果文件只有一个 commit,两者相同。
VitePress 的
lastUpdated读取同一文件最近一次 Git commit 的%ai(作者时间);date读取第一次 commit 的%ai。push 不会改变 commit 时间。只有文件尚未提交、使用浅克隆导致历史不完整,或手工改写提交历史时,二者关系才可能不可靠。
自动写入的 date 会使用双引号,例如 date: "2026-11-08 20:20:56"。这是为了让 YAML 把它解析为字符串,而不是无时区 Date;本站把无时区日期按东八区(+08:00)解释,手工覆盖日期时也建议保留双引号。
自动 frontmatter 在 docs/.vitepress/config.ts 的 vitePlugins.autoFrontmatterOption 中启用,但当前 exclude: { title: true, date: true } 会让它跳过已有普通 frontmatter 的文章;只有极少数空 frontmatter 文件才会得到自动补值。layout: home、layout: false 以及 @pages 等插件目录不走这套普通兜底。因此,不写不等于没有值,而是可能得到一个不适合长期维护的值。
| 省略字段 | 系统兜底行为 | 为什么文章必须显式写 |
|---|---|---|
title | 只有 frontmatter 完全为空时自动插件才可能按文件名补;正常文章不会;Teek 运行时还会用 H1/文件名兜底 | 文件名与文章标题经常不同,自动标题还可能和正文 H1 不一致 |
date | 文件第一次 Git commit 的作者时间;尚未提交时由文件创建时间临时兜底 | 不需要手填;首次提交后启动/构建会写入,之后稳定保留 |
permalink | 自动插件通常跳过已有 frontmatter;可能按 VitePress 源文件路径推导,不能得到稳定可读地址 | 链接不稳定,侧边栏路径不匹配,外部引用失效;必须写稳定的 /posts/... |
categories | 自动插件通常跳过已有 frontmatter;省略后没有可靠的分类推断 | 自动分类不适合作为 /categories 的最终聚合口径;文章应只写一级分类 |
coverImg | 不写时首页卡片先随机取正文图片,再随机取 /home/bg*.webp;SEO 分享图回退到站点默认图 | 需要固定卡片封面或固定分享图时才写;不写不会导致首页卡片没有图,但 SEO 分享图不会自动取正文图 |
article | 大多数文章相关代码使用 article !== false,所以省略时按文章处理 | 目录页或指南页若忘记写 false,可能进入首页文章列表、归档或 RSS |
sidebar | 省略时按显示处理;只有 sidebar: false 才关闭 | 目录页应明确关闭,文章应明确开启,便于检查 |
comment | 评论区组件使用 comment !== false,省略时默认显示 | 目录页和指南页应明确写 false |
pagefind-indexed | Pagefind 只把 pagefind-indexed: false 排除,省略时默认参与搜索 | 目录页和工具页应明确写 false |
top、sticky | 省略时不进入精选卡片,也不参与置顶排序 | 启用时再写,且不要把 top 当排名 |
updated | 不写时没有单独的 SEO 修改时间;文章 SEO 会退回 Git 时间和发布日期 | 只有确实需要覆盖 SEO 的 dateModified 时才写 |
只有空 frontmatter 文件可能触发自动插件写入;正常文章通常不会。无论是否触发,都不代替人工检查。只应该提交你理解并确认过的字段。稳定写法是:title、permalink、categories 和四个开关显式写;date 在首次 commit 后自动写入;coverImg 只在需要固定封面时写。
5. 字段完整手册
阅读表格时先看等级:
- 必填:文章或对应页面类型必须写;不写虽然可能有兜底,但不属于稳定维护。
- 推荐:强烈建议写;省略后可能出现不理想的自动值。
- 可选:只有需要某个效果时才写。
- 高级:理解 VitePress 或 Teek 行为后再写。
- 系统专用:只属于
docs/@pages/、首页或私密功能,普通文章不要写。 - 不可用:当前项目没有实现,写了也不会生效。
A. 身份、SEO 与路由
| 字段 | 类型 | 省略时默认 | 本站推荐 | 等级 | 作用 | 常见坑 |
|---|---|---|---|---|---|---|
title | string | 自动插件通常跳过;运行时可用 H1 或文件名兜底 | 与正文唯一的 H1 完全相同 | 必填 | 页面标题、浏览器标题、OG 标题、首页卡片、侧栏、目录页和搜索结果 | title 与 H1 不一致会让列表和正文看起来像两篇文章;不要用正文 H1 代替 title;不要写多个 H1 |
description | string | 空;SEO 退回 describe 或站点描述,首页卡片可能退回摘要 | 一句具体、可独立阅读的摘要,约 50 至 150 个汉字 | 必填(写作规范;系统有回退) | SEO description、OG 和社交分享描述、JSON-LD 描述、首页卡片摘要 | 只写 desc 不会自动成为首页卡片摘要;不要粘贴整段正文 |
desc | string | 空 | 文章不要写;仅旧目录页模板使用,并与 description 保持一致 | 遗留别名,不推荐;旧模板常称它为 SEO 别名 | 目录页头部会按 desc、description 顺序显示;首页卡片不读取它。当前 transformHead 的 SEO 回退实际读取 describe,不是 desc | 不要写 desc 来期待 SEO 或首页卡片变化;新文章只用 description;两个字段内容不同会导致目录页显示不同描述 |
date | string,格式为 yyyy-MM-dd hh:mm:ss;YAML 可能把裸时间解析为日期对象 | 文件第一次 Git commit 的作者时间;未提交时无自动值 | 通常省略;需要人工指定发布时间时才写 | 自动维护;通常不手填 | 首页和归档按日期从新到旧排序、日期展示、精选卡片日期、Pagefind 日期元数据、SEO 发布时间 | 读取的是文件首次 commit,不是 push/build 时间;不要为了更新内容改 date,更新用 updated 或 Git 最后更新时间;不要混用 2026/11/07 等格式 |
updated | string,同一日期格式;YAML 可能把裸时间解析为日期对象 | 无;SEO dateModified 退回 Git 时间和发布日期 | 通常省略;只有需要覆盖 SEO 修改时间时才写 | 高级、可选 | 只用于文章的 SEO article:modified_time 和 JSON-LD dateModified | 它不会自动显示在文章页,也不会改变首页或归档排序;页面上的更新时间通常来自 Git 的 lastUpdated |
permalink | string,站内绝对路径 | 自动插件通常跳过;可能按 VitePress 源文件路径推导,不稳定 | 一级文章 /posts/技术笔记/example;子目录文章 /posts/技术笔记/项目记录/example | 必填 | 固定页面 URL、侧栏链接、搜索清单路由、canonical、OG URL、RSS 和复制链接 | 不要写 docs/posts/...、完整域名或 .html;不要重复;必须与文章所在分类目录对应,否则侧栏可能匹配不到 |
coverImg | string 或 string[],站内路径或完整 URL | 首页卡片:正文图片随机 → /home/bg*.webp 随机;SEO 图片:站点默认图 | 只在需要固定封面或固定分享图时填写真实路径;否则省略 | 可选(按需) | 显式指定后首页卡片固定使用它;文章 Banner、OG 和社交分享图也会读取。不写时首页卡片仍会随机,但 SEO 分享图不会自动取正文图片 | 路径是相对 docs/public/ 的站内地址,不要写 docs/public/home/bg11.webp;图片不存在会 404;显式写后不会再随机 |
A 组最重要的四个区别:
title管元数据和列表,H1 管正文可见标题。 两者应一致;文章正文第一段之前只放一个 H1。date管发布时间和排序,updated只管 SEO 修改时间。 想把文章排到前面用sticky,不要改updated。permalink是稳定链接,不是根据 frontmatter 自动推导的装饰。 本项目的cleanUrls: true,所以地址不写.html;生成后的路径由transformHead用于 canonical 和社交元数据。description是主字段,desc只是旧目录页的兼容显示回退。 首页卡片读取的是description,不是desc。
日期统一按 yyyy-MM-dd hh:mm:ss 原样写,例如 2026-11-07 12:00:00。这里的 hh 是该主题格式化函数的小时字段;本站模板不使用 2026/11/07 或带时区的 ISO 写法,避免显示、排序和 SEO 时间出现不必要的时区差异。
首页文章卡片的封面选择顺序
首页 postStyle: "card" 的文章卡片按以下顺序选择封面:
- 显式
coverImg优先。 写了字符串就固定使用该图片;写数组则在数组内随机。 - 没有
coverImg时,优先随机使用正文图片。 当前实现会收集正文 Markdown 图片和 HTML<img src="/...">,只接受以/开头的站内绝对路径或http(s)外部地址;代码块、HTML 注释中的图片不计入。 - 正文也没有可识别图片时,从
/home/bg0.webp到/home/bg31.webp随机。
随机发生在浏览器端,每次打开或刷新首页都会重新抽取。SSR 首屏可能先使用候选列表中的第一张,挂载后替换为随机结果。正文使用相对图片路径(如 ./a.webp)不会可靠进入候选列表,建议使用 /images/posts/... 站内绝对路径。
注意:本规则只作用于首页文章卡片。如果希望社交分享图也稳定,仍需显式写 coverImg;不写时 SEO 使用站点默认分享图。
B. 分类、标签与作者
| 字段 | 类型 | 省略时默认 | 本站推荐 | 等级 | 作用 | 常见坑 |
|---|---|---|---|---|---|---|
categories | string[] | 自动插件通常跳过已有普通 frontmatter;没有可靠分类默认值 | 只写一个一级分类,例如 技术笔记、生活随笔、算法竞赛 | 必填 | 首页文章信息、/categories 分类页、分类卡片和分类聚合 | 即使文章在二级目录,也保持一级分类;不写会缺少可靠的分类聚合;不要写成一串用逗号分隔的文本,也不要写单数 category 代替它 |
tags | string[] | 空数组,不进入标签聚合 | 2 到 5 个具体主题词,例如 VitePress、部署、排错 | 推荐 | /tags 标签页、标签卡片、文章信息、关键词元数据、标签过滤和相关内容推荐 | 不要把一级分类重复成标签;标签不是目录;不要塞入十几个同义标签 |
author | 对象 { name: string, link?: string } | 使用站点配置 { name: "Baecon", link: "/" } | 通常省略 | 可选;一般不需要 | 覆盖首页卡片和文章信息处显示的作者;不影响页面 H1 或站点配置 | 如果写字符串,文章信息组件读取不到 author.name;覆盖时要保持对象形状,且 SEO 作者仍取站点配置 |
C. 可见性、首页与排序
| 字段 | 类型 | 省略时默认 | 本站推荐 | 等级 | 作用 | 常见坑 |
|---|---|---|---|---|---|---|
article | boolean | 实际按 true 处理,因为多处判断是 article !== false | 文章 true;目录页和指南页 false | 推荐显式写 | 控制文章数据是否进入首页列表、分类/标签聚合、归档、RSS 和自定义搜索清单;/posts/ 下还影响 JSON-LD 类型 | 写 false 不等于下架,也不自动退出 Pagefind;若页面仍在 /posts/,阅读进度和相关内容仍可能按路径显示 |
sidebar | boolean | 默认显示;只有 false 才关闭 | 文章 true;目录页和指南页 false | 推荐显式写 | 控制 VitePress 左侧栏;docs/.vitepress/sidebar.ts 会跳过 sidebar: false 的文章。当前扫描器不读取 article 字段,因此 article: false 本身不会移除侧栏条目 | 关闭侧栏不会关闭搜索或评论;随机 permalink 不匹配 /posts/<分类>/ 时,侧栏也可能不出现 |
sidebarSort | 正数 number | 无;退回文件名数字前缀,再按标题排序 | 通常省略;需要调整时用 10、20、30 | 高级 | 只影响同一目录内文章在左侧栏和 search-manifest 文章列表中的顺序,数字越小越靠前 | 不影响首页文章顺序、归档、精选卡片或 RSS;它不影响目录层级本身的顺序;子目录顺序看目录名数字前缀,一级分类顺序看 sidebar.ts 和 search-manifest.ts 的 categoryOrder;不要写引号 |
pagefind-indexed | boolean | 实际按 true 处理;只有严格 false 才排除 | 文章 true;目录页、指南页和工具页 false | 推荐显式写 | 控制 Pagefind 是否给页面建立全文搜索索引 | 必须写裸布尔值 false;false 只排除搜索,不会设置 robots: noindex,也不会自动移除 sitemap;article: false 单独也不会关闭 Pagefind |
comment | boolean | 实际按 true 处理,因为组件判断是 comment !== false | 文章 true;目录页和指南页 false | 推荐显式写 | 控制 Twikoo 评论区是否渲染;组件位于 Teek 的 doc-after 插槽,主要作用于文章详情布局 | 目录页使用 layout: page、写作指南使用 layout: doc,都应显式 false;comment: true 只表示允许,仍需站点评论配置可用;必须写裸布尔值 false,写成字符串 "false" 仍会被当作显示 |
top | boolean 或数字,代码按真值判断 | 不进入精选卡片 | 只有需要出现在精选卡片时写 1(任意真值也可) | 可选 | 精选文章卡片的入选条件;卡片内顺序仍由 sticky 和 date 决定 | 它不是数字排名。docs/posts/技术笔记/项目复盘模板.md 里的 top: 1 能生效,但不要因此写 top: 2 期待第二名;top: 0 或 false 不会入选 |
sticky | number | 无置顶;按日期降序 | 通常省略;需要置顶时用正整数,例如 1、10 | 可选、高级 | 在首页文章列表和精选卡片排序时把文章放到前面;两个都有 sticky 时数字小的在前,相同数字再按日期降序 | 不影响归档顺序和相关内容排序;不是精选卡片的入选开关;不要把布尔值或字符串当排序值;不要给太多文章加置顶 |
inHomePost | boolean | 实际按 true 处理,只有严格 false 才隐藏 | 通常省略;只有明确不想出现在首页主文章列表时才写 false | 高级 | 只影响 HomePost 文章列表的可见性,主要用途是隐藏首页主列表;分类/标签页复用这个列表时也应用同一过滤 | 不会改变精选卡片、左侧栏、分类/标签聚合数据、归档、RSS 或 Pagefind;不是下架开关 |
inCatalogue | boolean | true | 通常省略;明确不想让文章出现在目录页时写 false | 高级 | 控制 vitepress-plugin-catalogue 是否把文章列入 path 扫描结果。 | 不影响侧边栏、Pagefind、首页、归档或 RSS。 |
titleTag | string | 无标题旁标签 | 通常省略;需要时用很短的词,例如 教程、排错 | 高级 | 在首页卡片标题、目录条目等标题组件旁显示短标签;自动注入 H1 时还可能加入 H1;手动写的 H1 不会自动获得该标签 | 它不替代 title、categories 或 tags;太长会挤压布局;不是所有页面类型都会显示 |
C 组最容易混淆的是三个排序概念:
| 想改变什么 | 使用字段 | 不要误用 |
|---|---|---|
| 这篇文章是否进入精选卡片 | top: true | sticky 只控制顺序,不会让文章入选精选卡片 |
| 文章在首页列表和精选卡片中的先后 | sticky,数字越小越靠前 | sidebarSort 只管左侧栏和搜索清单 |
| 文章在左侧栏和搜索清单中的先后 | sidebarSort,或文件名前缀 01.slug.md | date 管文章时间,不负责导航排序 |
top 是入选条件,sticky 是排序权重,sidebarSort 是导航排序。三个字段互相独立,不要为了同一个视觉效果同时打开。
D. VitePress 布局与页面级配置
| 字段 | 类型 | 省略时默认 | 本站推荐 | 等级 | 作用 | 常见坑 |
|---|---|---|---|---|---|---|
layout | string 或 false | doc,即文章详情布局 | 文章和写作指南省略或写 doc;目录页写 page;系统页按模板 | 页面类型必填 | 决定使用 VitePress 的文档布局、普通页面布局、首页布局或完全自定义布局 | 目录页忘记写 page 会进入文档布局;指南不要写 home;false 会移除常规导航和页脚,只适合系统页 |
outline | false、数字、[number, number] 或 "deep" | 继承 themeConfig.outline:当前为 2 至 4 级标题,标题文字为本页导航 | 通常省略;只想关闭右侧本页导航时写 false | 高级 | 控制文章右侧本页目录显示的标题层级 | 当前 VitePress 版本不把 outline: true 当作有效配置;数字或数组控制层级;页面级对象里的 label 不要依赖,目录标题来自站点配置 |
aside | boolean 或 "left" | 主题默认显示右侧栏 | 通常省略 | 高级 | 在文档布局中显示或隐藏整个右侧区域,left 可把右侧栏移到左边 | 它不控制左侧文章导航;aside: false 不是 sidebar: false;layout: page 本身没有文档右侧栏,写了通常看不到效果 |
lastUpdated | boolean | 继承站点 lastUpdated: true,读取 Git 最后提交时间 | 通常省略;不需要此页时间时写 false | 高级 | VitePress 页脚最后更新时间;也供 Teek 文章信息中的更新时间读取 | 它是 VitePress 层级字段,不是 SEO 的 updated;写 false 也不会清除 updated,但可能让 SEO 修改时间少一个 Git 兜底 |
editLink | boolean | 站点配置了编辑链接模板时默认显示,否则不显示 | 通常省略 | 高级 | 控制当前页是否显示站点级编辑链接 | 当前 docs/.vitepress/config.ts 没有配置 themeConfig.editLink,所以单独写 editLink: true 不会生成链接;它不能在这里直接填 URL |
pageClass | string | 无额外类名 | 通常省略;需要页面级样式时写一个自定义类 | 高级 | VitePress 会把类名加到根布局 .Layout 上,可配合自定义 CSS 做整页样式 | 需要先在样式文件里写好对应选择器,否则没有可见效果;它不是切换布局的开关 |
layoutClass | string | 无额外类名 | 通常省略 | 高级 | 当前项目在 docs/.vitepress/theme/index.ts 中读取该字段并作为布局组件 class,需配套 CSS 才有意义。 | 普通文章不要写;需要页面级样式时优先使用 pageClass。 |
head | 数组,元素为 [标签名, 属性对象] 或 [标签名, 属性对象, 内容] | 不追加页面级标签 | 通常省略 | 高级 | 向当前页 HTML <head> 合并 meta、link、script 等标签 | YAML 嵌套数组易写错;本站 transformHead 已统一生成 canonical、robots、description、OG 和 JSON-LD,页面级重复标签可能冲突 |
titleTemplate | string 或 boolean | 继承站点模板;当前未配置模板,因此浏览器标题默认是页面标题加站点标题后缀 | 通常省略 | 高级 | 只影响浏览器 <title> 的拼接方式;false 表示不加站点后缀,字符串中的 :title 会替换为页面标题 | 不改变 H1、首页卡片和 transformHead 生成的 OG 标题;首页 docs/index.md 用它覆盖站点后缀,普通文章不要跟风 |
prev | boolean | true(有上一页时) | 省略 | 高级 | 设为 false 隐藏文档底部上一页链接。 | 仅在文档布局且存在上一页时有意义。 |
next | boolean | true(有下一页时) | 省略 | 高级 | 设为 false 隐藏文档底部下一页链接。 | 仅在文档布局且存在下一页时有意义。 |
coverBgColor | string | 跟随站点 defaultCoverBgColor,本站为空 | 省略 | 高级 | 单文章 Banner 背景色覆盖。 | 没有 Banner 时不可见;使用合法 CSS 颜色。 |
articleBanner | boolean 或 object | 跟随站点配置;本站开启 | 省略 | 高级 | 设为 false 可关闭单文章 Banner。 | 通常只在无侧边栏的 doc 布局文章生效。 |
articleUpdate | boolean 或 object | 跟随站点配置,默认启用 | 省略 | 高级 | 设为 false 可隐藏文章页最近更新模块。 | 不影响页面正文、评论或其他文章数据。 |
autoTitle | boolean | 在 doc 布局下默认允许 md-h1 插件注入标题 | 省略;正文已经手写 H1 | 高级 | 控制自动 H1 注入。 | false 可禁止自动注入;文章正文仍必须有一个手写 H1。 |
E. 目录页专用
| 字段 | 类型 | 省略时默认 | 本站推荐 | 等级 | 作用 | 常见坑 |
|---|---|---|---|---|---|---|
catalogue | boolean | false | 只写在 docs/catalog/ 的目录页,值为 true | 目录页必填 | 触发 Teek 目录插件扫描 path 并把目录列表渲染到页面顶部 | 不是文章字段;没有合法的 path 时会得到空目录或警告;新增或修改后需要重启开发服务 |
path | string,相对 docs/ 的目录路径 | 空 | posts/技术笔记 或 posts/技术笔记/项目记录 | 目录页必填 | 指定要被扫描的文章目录,插件会递归列出其中的 Markdown 文件 | 按 posts/技术笔记 形式写,不要加 docs/ 前缀;路径不存在会警告;文章目录中不要放 index.md |
pageTitle | string | 主题语言包中的目录 | 文档目录 | 推荐 | 显示在目录列表上方的列表标题,方便读者理解下方内容是文章目录 | 它不控制浏览器标题或页面大标题;页面大标题用 title,不要混用 |
F. 系统专用字段,不要写进普通文章
| 字段 | 类型 | 省略时默认 | 本站推荐 | 用在哪里 | 等级 | 作用与坑 |
|---|---|---|---|---|---|---|
categoriesPage | boolean | false | 保持系统页现状;文章不写 | docs/@pages/categoriesPage.md | 系统专用 | 让分类页进入分类聚合状态,配合 /categories 页面和 layout: home。普通文章写了不会变成分类页,反而可能影响文章数据判断 |
tagsPage | boolean | false | 保持系统页现状;文章不写 | docs/@pages/tagsPage.md | 系统专用 | 让标签页进入标签聚合状态,配合 /tags 页面和 layout: home。不是文章标签字段,标签内容用 tags |
archivesPage | boolean | false | 保持系统页现状;文章不写 | docs/@pages/archivesPage.md | 系统专用 | 让 Teek 在页面顶部挂载归档组件并登记归档页路径;配合 layout: page、article: false、sidebar: false。普通文章不要写 |
articleOverviewPage | boolean | false | 保持系统页现状;文章不写 | docs/@pages/articleOverviewPage.md | 系统专用 | 生成文章清单页并登记路径;不是文章正文开关。普通文章不要写 |
riskLinkPage | boolean | false | 保持系统页现状;文章不写 | docs/@pages/riskLinkPage.md | 系统专用 | 显示站外链接风险提示页,通常配合 layout: false 和站点 riskLink 配置。该页还会读取 logo、name、desc、linkIllegal 等系统 UI 字段,普通文章不要复制 |
loginPage | boolean | false | 保持关闭;文章不写 | 私密访问登录页 | 系统专用 | 触发 Teek 登录页。当前站点 private.enabled: false,普通文章不需要、也不应该开启 |
showUpdateDate | boolean | 未设置 | 文章不要写 | 主题文章信息配置 | 遗留/无效字段 | 当前主题的更新时间显示由站点 articleAnalyze.showUpdateDate 控制,frontmatter.showUpdateDate 没有被文章信息组件读取,写了也不会关闭更新时间;文章需要固定时间时使用 updated(只影响 SEO)或依赖 Git lastUpdated。 |
loginInfo | 对象数组 { username, password, expire?, session?, strategy? } | 空 | 不要使用;文章不写 | 私密文章或系统登录流程 | 系统专用 | 为单页私密访问提供账号配置;当前私密功能未启用。普通文章不要放账号密码,凭据会进入仓库和客户端页面数据,不能当作安全存储 |
tk | 对象,键名是 Teek 配置项 | 空 | 仅特殊页面使用;文章不写 | docs/index.md 等特殊页面 | 系统专用 | 页面级覆盖部分 Teek 主题配置,例如首页示例中的 tk.teekHome: true。键名写错不会生效,而且可能破坏页面布局;普通文章不要用它代替标准 frontmatter |
系统页的模板由仓库维护者负责。普通作者只需要知道:这些字段不是文章字段,不要在 docs/posts/ 的文件里尝试。
站点级固定设置不是 frontmatter 字段
| 位置 | 当前行为 | 是否要写进 frontmatter |
|---|---|---|
docs/.vitepress/config.ts 的 cleanUrls: true | 页面 URL 不带 .html | 不用;permalink 仍然必须写 |
docs/.vitepress/config.ts 的 lastUpdated: true | 用 Git 提交历史显示更新时间 | 只有要关闭时才写 lastUpdated: false |
articleAnalyze.dateFormat: "yyyy-MM-dd hh:mm:ss" | 控制文章日期显示格式 | 不用;date 和 updated 按该格式写 |
markdown.lineNumbers: true 和 markdown.image.lazyLoading: true | 全局启用代码行号和图片懒加载 | 不用,没有对应的普通文章开关 |
vitePlugins.docAnalysisOption.ignoreList | 已忽略 pages、catalog、writing-guide、search.md 的字数统计 | 不用;这是站点配置,不是页面字段 |
docs/.vitepress/theme/config/teekConfig.ts 与 TeekLayoutProvider.vue 注入的 post、page、topArticle、homeCardListPosition | 控制首页列表样式、每页数量、精选卡片数量和卡片位置。当前关键值为 post.showCapture: false、page.pageSize: 30、topArticle.limit: 4、homeCardListPosition: "left" | 不用;不要把这些站点配置名写进文章 frontmatter |
6. 字段之间的关系
6.1 title、H1 与自动标题
title是页面元数据、浏览器标题、卡片标题、侧栏文字和目录条目的首选来源。- H1 是正文里文章的大标题。文章应该在 frontmatter 之后、正文引入文字之前立即写唯一一个
# 标题。 - 文章没有 H1 时,Teek 的 Markdown H1 插件会在默认
doc布局下用frontmatter.title或文件名注入一个 H1。这个注入发生在构建加载时,不会真正修改 Markdown,所以不要依赖它来补救错误结构。 - 写作指南页使用
layout: doc时仍应自己写唯一一个 H1;目录页使用layout: page,由 Teek 的目录组件负责页面结构,正文不要额外造 H1。 - 如果正文先写导语再写 H1,H1 插件会把第一行视为非 H1,可能再注入一个,造成两个 H1。把 H1 放在最前面。
6.2 description、desc、首页卡片与 SEO
首页文章卡片的摘要优先级大致是:frontmatter.description,然后是文章摘要来源(例如 <!-- more -->),最后才可能在开启截取时使用正文。desc 不参与这条首页卡片判断。
SEO 端 docs/.vitepress/config.ts 的 transformHead 按 description、describe、站点描述的顺序取描述,并写入 meta、OG、Twitter、微信分享和 JSON-LD。desc 常被旧模板当作 SEO 别名,但注意这里读取的是 describe,不是 desc;目录组件才读取 desc。因此:
- 新文章只写
description。 - 目录页旧模板可以同时保留相同的
description和desc,不要写两个不同版本;但 SEO 仍应只依赖description。 describe只是transformHead里的内部回退键名,不是本站推荐字段;不要用它替代description。- 不要把正文整段塞进
description,它会被当作文本直接输出。
6.3 categories 与磁盘目录
磁盘目录决定文章文件的物理位置,以及左侧栏、目录页扫描结构;categories 决定 /categories 和分类卡片如何聚合文章。
- 一级目录与一级分类应一致,例如
docs/posts/技术笔记/对应categories: [技术笔记]。 - 文章放进二级目录后,物理路径和
permalink可以包含二级目录,但categories仍保持一级分类。 - 分类页和标签页展示的是 frontmatter 聚合,不是文件树本身。
- 省略
categories时,自动插件按目录推断,可能把posts和二级目录也写进分类,导致分类卡片出现不该出现的层级。
6.4 tags 与 categories
| 项目 | categories | tags |
|---|---|---|
| 数量 | 通常一个一级分类 | 推荐 2 到 5 个具体主题 |
| 作用 | 站点的大类导航和归档 | 跨分类的主题检索、标签卡片和相关内容匹配 |
| 是否对应目录 | 是,一级目录应与一级分类一致 | 否,标签不创建磁盘目录 |
| 例子 | 技术笔记 | VitePress、部署、排错 |
不要把分类名重复成标签,也不要用标签替代目录结构。
6.5 top、sticky、sidebarSort 与 date
top: true只决定文章是否进入精选卡片。它不是名次,数字本身没有排名含义。sticky决定首页文章列表和精选卡片的先后顺序:有sticky的排在无sticky的前面,多个sticky数字小的在前,数字相同再按date从新到旧。sidebarSort只改变同一目录文章在左侧栏和search-manifest中的顺序;文件名前缀01.、02.也是同一套导航排序的兜底。date是发布时间,影响首页、归档、日期显示和默认排序。updated不参与这些排序。date也参与文章是否显示过时提示的判断。不要为了排序把日期写成未来或随意改日期;排序需求应使用sticky。
6.6 article、sidebar、pagefind-indexed、comment 是四个独立开关
| 目标 | article | sidebar | pagefind-indexed | comment | 额外字段 |
|---|---|---|---|---|---|
| 正常文章 | true | true | true | true | 无 |
| 只不在首页主列表出现 | true | true | true | true | inHomePost: false |
| 只不在目录页出现 | true | true | true | true | inCatalogue: false |
| 只关闭评论 | true | true | true | false | 无 |
| 只退出全文搜索 | true | true | false | true | 无 |
| 只退出左侧栏 | true | false | true | true | 无 |
| 目录页或指南页 | false | false | false | false | 目录页还需 layout: page、catalogue: true、path |
注意:article: false 不会自动关闭 Pagefind、侧边栏或目录页扫描;隐藏侧栏用 sidebar: false,隐藏目录条目用 inCatalogue: false。不要只改一个开关就期待所有入口同时消失。
Pagefind 是全文搜索索引,docs/public/search-manifest.json 是另一份文章和目录清单;后者由 docs/.vitepress/search-manifest.ts 生成,不要手改。docs/.vitepress/plugins.ts 中 Pagefind 读取 pagefind-indexed,RSS 过滤器则读取 article !== false,两者不是同一个条件。
6.7 页面路径、文章识别与站点页脚
docs/.vitepress/theme/components/TeekLayoutProvider.vue 里的 isArticle 只看路由是否以 /posts/ 开头,不看 frontmatter 的 article:
/posts/...页面会显示阅读进度和相关内容,并隐藏自定义站点页脚。layout !== "home" && !isArticle时才显示TkFooterInfo,所以目录页和指南页会显示站点页脚。- 目录页必须放在
docs/catalog/,指南必须放在docs/writing-guide/。如果为了图方便把目录页放进docs/posts/,即使写article: false,仍可能被当成文章路径处理。
文章数据、首页卡片、分类/标签聚合、RSS 和自定义搜索清单则主要依据 frontmatter.article !== false。两条判断口径不同,这也是目录页不能放进 docs/posts/ 的原因。
实现边界:docs/.vitepress/sidebar.ts 只扫描 docs/posts,跳过 index.md 和以 _、. 开头的项,并排除 sidebar: false 的文件(当前不读取 article);docs/.vitepress/search-manifest.ts 只扫描 docs/posts,跳过 index.md 和隐藏项,按 article !== false 过滤,并按 sidebarSort 或文件名数字前缀排序。目录页扫描另外看 inCatalogue。
7. 可复制模板
模板里的可选字段全部处于注释状态。不要一次性取消所有注释。 普通文章先只改标题、描述、永久链接、分类、标签和封面;date 由 Git 首次提交自动写入;top、sticky、titleTag、sidebarSort、inHomePost、updated、outline、lastUpdated 只有在明确需要对应效果时才启用,通常一篇文章最多用一两项。
top、sticky、inHomePost、sidebarSort 主要属于文章列表;目录页和指南页模板刻意不包含这些字段,不要因为看到文章模板就照抄。
7.1 一级分类文章模板
文件位置示例:docs/posts/技术笔记/03.example-top-level.md
---
title: 示例文章:一级分类
description: 用一句话说明这篇文章讲了什么,以及读者能获得什么。
permalink: /posts/技术笔记/example-top-level
categories:
- 技术笔记
tags:
- 示例
- 写作规范
article: true
sidebar: true
pagefind-indexed: true
comment: true
# 下面是可选项,不要全部启用:
# top: 1
# sticky: 10
# titleTag: 教程
# sidebarSort: 10
# inHomePost: false
# updated: 2026-11-08 12:00:00
# outline: false
# lastUpdated: false
---
# 示例文章:一级分类
一句话导语,可选。
## 背景
说明为什么要写这篇文章。
## 操作步骤
1. 写清楚前置条件;
2. 给出可复现的步骤;
3. 说明如何验证结果。
```bash
pnpm docs:dev
```
## 常见问题
| 问题 | 原因 | 解决方案 |
| --- | --- | --- |
| 示例问题 | 示例原因 | 示例解决方案 |
## 总结
总结读者最应该记住的结论。复制后至少修改 title、description、permalink、tags;date 不要手填。coverImg 是可选项:不写时首页卡片按正文图片或随机 bg*.webp 选择,只有需要固定封面/分享图时才填写。permalink 必须全站唯一,并且与一级分类目录保持一致;正文 H1 必须与 title 一致。
7.2 子目录文章模板
文件位置示例:docs/posts/技术笔记/项目记录/01.example-subdir.md
---
title: 示例文章:子目录
description: 说明子目录文章仍然沿用一级分类,但永久链接需要包含子目录。
permalink: /posts/技术笔记/项目记录/example-subdir
categories:
- 技术笔记
tags:
- 项目记录
- 示例
article: true
sidebar: true
pagefind-indexed: true
comment: true
# 下面是可选项,不要全部启用:
# top: 1
# sticky: 10
# titleTag: 复盘
# sidebarSort: 20
# inHomePost: false
# updated: 2026-11-08 12:00:00
# outline: false
# lastUpdated: false
---
# 示例文章:子目录
一句话导语,可选。
## 项目背景
记录目标、使用场景和约束条件。
## 实施过程
1. 需求拆解;
2. 方案设计;
3. 开发与联调;
4. 验证和发布。
## 结果与复盘
记录结果、指标和下次要保留的做法。
## 总结
写下最重要的经验。关键点:文件可以在 docs/posts/技术笔记/项目记录/,permalink 可以写 /posts/技术笔记/项目记录/example-subdir,但 categories 仍然只写一级分类 技术笔记。不要把 项目记录 写成第二个一级分类。
7.3 目录页模板
文件位置示例:docs/catalog/技术笔记/项目记录.md
---
title: 项目记录
description: 项目开发、架构设计和复盘记录。
layout: page
catalogue: true
path: posts/技术笔记/项目记录
pageTitle: 文档目录
permalink: /catalog/技术笔记/项目记录
sidebar: false
article: false
pagefind-indexed: false
comment: false
---目录页只保留 frontmatter,不需要正文,也不要在正文里再写 H1。目录内容由 Teek 扫描 path 自动生成。复制后必须同时修改 title、description、path、permalink;如需固定目录封面再修改 coverImg。path 不存在时页面会没有目录或出现警告。新增或修改 catalogue: true 后要重启开发服务。
7.4 指南或工具页模板
文件位置示例:docs/writing-guide/example-guide.md
---
title: 示例写作指南
description: 说明这个指南解决什么问题,以及适合谁阅读。
permalink: /writing-guide/example-guide
layout: doc
sidebar: false
article: false
pagefind-indexed: false
comment: false
coverImg: /home/bg23.webp
---
# 示例写作指南
一句话导语,可选。
## 适用场景
说明这份指南适合谁、什么时候使用。
## 操作步骤
1. 第一步;
2. 第二步;
3. 第三步。
## 检查清单
- [ ] 链接可以打开;
- [ ] 示例可以复现;
- [ ] 没有多余 H1。指南页不是文章:不要写 categories、tags、top 或 sticky。正文保留唯一一个 H1,并确保 permalink 位于 /writing-guide/ 下。
8. 常见错误与修复
| 现象 | 常见原因 | 修复方式 |
|---|---|---|
文章 URL 是旧 /pages/xxxxxx | 历史随机 permalink 或缺少显式地址 | 补写稳定的 /posts/<一级分类>/<slug>;子目录文章把子目录写进 URL;不要保留随机值 |
| 首页没有文章卡片 | article: false、layout: home、inHomePost: false,或文章被当成了系统页 | 确认文章在 docs/posts/ 且 article: true、inHomePost 不是 false;不要给普通文章写 layout: home |
| 文章没有左侧栏 | sidebar: false、文件在 docs/posts/ 之外、文件名是 index.md,或 permalink 不在 /posts/<分类>/ 下 | 把文章放回 docs/posts/<分类>/,开启 sidebar,使用稳定的 /posts/... 地址;article: false 不影响侧栏 |
| 搜索不到文章 | pagefind-indexed: false,或只在开发服务器里找而没有执行构建 | 改成 true,运行 pnpm docs:build 生成搜索索引;同时确认没有因空正文被跳过 |
| 分类页没有这篇文章 | categories 缺失或写错,或 article: false 让文章没有进入聚合数据 | 显式写一级分类数组,例如 categories: [技术笔记],并保持 article: true |
| 精选卡片没有这篇 | 没有写 top: true,写成了 top: 0,或文章 article: false、layout: home 被排除 | 给真正需要推荐的文章写 top: true;检查文章数据和精选卡片的显示上限 |
| 正文出现两个 H1,或指南页没有 H1 | 文章在 H1 前写了导语,自动 H1 插件又注入一个;指南页使用 layout: doc 时不要依赖自动 H1,请手动写且只写一个 H1 | 文章把唯一 H1 放在正文最前面;指南页手动写且只写一个 H1;目录页不要写正文 H1 |
| 封面或正文图片 404 | 把 docs/public 写进了 URL,或用相对路径但文件并不在 Markdown 同级 | 站内路径应写成 /home/bg11.webp 或 /images/posts/...;确认文件在 docs/public/ 下且大小写一致 |
| 目录页出现侧栏、评论或搜索 | 少了 sidebar: false、comment: false、pagefind-indexed: false,或没有使用 layout: page | 目录页同时设置 layout: page、article: false、sidebar: false、comment: false、pagefind-indexed: false;确认文件在 docs/catalog/ |
| 构建时 frontmatter 解析失败 | 使用中文冒号、Tab 缩进、漏掉闭合 ---、引号不配对或键重复 | 按第 2 节逐行检查 YAML;先去掉可疑字段,再重新启动并构建 |
9. 发布前最终检查清单
- 文件放对位置:文章在
docs/posts/,目录页在docs/catalog/,指南在docs/writing-guide/。 - Frontmatter 从第一行
---开始,并用单独一行---正确闭合。 - 没有中文冒号、Tab 缩进、漏引号或重复键。
title与正文唯一 H1 一致。- 文章正文只有一个 H1,且位于正文最前面;指南页也只能有一个 H1;目录页正文为空。
- 没有手写
date;文件首次 commit 后运行启动/构建,已自动写入yyyy-MM-dd hh:mm:ss,后续保持稳定。 permalink以/posts/或/catalog/或/writing-guide/开头,全站唯一,不带.html。- 一级文章
categories与docs/posts/<分类>/对齐;子目录文章仍只写一级分类。 tags是数组,数量适中,没有把分类名重复成标签。- 如果写了
coverImg,它指向docs/public/下真实存在的文件,URL 不包含docs/public/;使用外部 URL 时确认地址可访问。 - 文章四个开关为
true;目录页和指南页四个开关为false。 top只作为精选入选条件;sticky和sidebarSort没有和date混用。- 确需使用
inHomePost、titleTag、updated、outline、lastUpdated时,已经理解各自只影响哪一层。 - 目录页的
path相对于docs/,指向真实文章目录,并已重启开发服务。 - 本地执行
pnpm docs:build后,首页、侧栏、目录、搜索和评论均符合预期。

