Skip to content

Markdown 写作基础与本站扩展 ​

读者对象:会一点 Markdown,但还没有在本站正式写过文章的初学者。

读完本页,你应该能独立完成一篇结构清楚、图片路径正确、代码块可读、能被本站主题正常渲染的文章,并知道写完后如何自检。

本页属于「写作指南」,不是博客文章。因此页面使用 layout: doc、article: false、sidebar: false、comment: false,以获得标准 Markdown 正文样式。普通博客文章的 frontmatter 会在下文单独给出。

先分清 Frontmatter 和正文 ​

什么是 Frontmatter ​

Frontmatter 是 Markdown 文件最顶部的一段「元数据」。元数据不直接显示在文章正文里,而是告诉 VitePress 和 Teek 主题:这篇文章叫什么、摘要是什么、访问地址是什么、是否显示侧边栏、是否参与搜索等。

「元数据」可以理解为「给程序看的配置」。正文才是「给读者看的内容」。

本站普通文章通常写成下面这样:

yaml
---
title: 用一个可读的标题说明文章内容
description: 一句话说明读者读完能得到什么。
permalink: /posts/技术笔记/example-article
categories:
  - 技术笔记
tags:
  - VitePress
  - Markdown
article: true
sidebar: true
pagefind-indexed: true
comment: true
---

常用字段如下:

字段作用本站文章中的写法
title浏览器标题、搜索结果标题、文章卡片的标题来源之一必填,简洁明确
description摘要,供首页、SEO 描述和分享卡片使用建议 50–150 个中文字符
date文章创建时间;文件首次 Git commit 后自动写入通常省略,不手填
permalink文章最终访问路径必须是唯一的 /posts/... 路径
categories分类与 docs/posts/ 下的一级目录一致
tags标签用 YAML 列表写 2–5 个,具体且可检索
coverImg固定封面图;不写则首页卡片随机选图可选;需要固定卡片/分享图时写真实站内路径
article是否按文章处理,是否进入文章集合普通文章写 true
sidebar是否显示文章左侧栏普通文章写 true
pagefind-indexed是否进入 Pagefind 搜索索引普通文章写 true
comment是否显示评论区普通文章写 true

top: 1 是可选的「精选文章」标记,不是每篇文章都必须写。不要为了凑字段而复制不理解的配置。

Frontmatter 必须从文件第一行开始 ​

Frontmatter 的规则很严格:

  1. 文件第一行必须是 ---;
  2. YAML 键值写在两条分隔线之间;
  3. 用单独一行的 --- 结束;
  4. 整个文件只能有一个 frontmatter 区块;
  5. 结束分隔线后空一行,再写正文 H1。

正确结构:

markdown
---
title: 文章标题
description: 文章摘要
---

# 文章标题

正文从空行之后开始。

错误示范:在正文前又写了一次分隔符。

markdown
---
title: 文章标题
description: 文章摘要
---

---

# 文章标题

第二个 --- 不会再次开启 frontmatter,通常会被当作正文中的分隔线,导致页面结构混乱。还有一种常见错误是把 frontmatter 放在 H1 后面;它不会再被识别为元数据,而会原样出现在页面中。

正文必须有且只有一个 H1 ​

在本站:

  • title 是 frontmatter 字段,不是正文标题;
  • 正文的 # 标题 是页面的 H1;
  • 一篇页面必须且只能有一个 H1;
  • 其余章节从 H2 开始。

正确:

markdown
# 一篇文章只有一个 H1

## 这是 H2 主章节

### 这是 H3 子章节

错误:

markdown
# 第一个 H1

# 第二个 H1

为什么必须只有一个 H1?因为 H1 表示页面唯一的主标题,浏览器、屏幕阅读器和 pnpm docs:audit 的 SEO 检查都会据此判断页面结构。缺少 H1 或多个 H1 都可能让审计报错。

pagefind-indexed: false 只表示「不进入站内搜索」,并不表示「不需要正确页面结构」。写作指南页面同样需要 H1。

空行不是装饰,而是 Markdown 语法的一部分 ​

Markdown 用空行分隔块级内容。标题、段落、列表、表格、代码块、容器前后都建议留一个空行。少一个空行,内容可能被合并进上一段,或者让代码块、容器无法按预期结束。

推荐习惯:

内容前面留空行后面留空行
标题是是
段落是是
列表是是
表格是是
围栏代码块是是
::: tip 等容器是是
时间线 ::: timeline是是
图片是是

一个结构正确的短例子:

markdown
# 文章标题

这是第一段正文。

## 第一节

- 第一项
- 第二项

上面列表结束后空一行,再写下一段。

常见错误速查 ​

现象常见原因修改方法
页面顶部出现 title: ... 文本没有从第一行写 ---,或结束分隔线写错让 frontmatter 从文件第一行开始
元数据没有生效两条 --- 后面又写了一段 frontmatter删除多余区块,只保留顶部一个
页面出现两个大标题写了两个正文 H1删除一个,把后续章节降为 H2/H3
标题和段落黏在一起标题前后没有空行标题前后各留一个空行
列表被当成普通文字列表前没有空行,或缩进不一致列表前后空行,嵌套统一缩进
代码块没有高亮开头的围栏后没写语言标签写 bash、ts、json、markdown 等

标题层级:H1 到 H6 ​

Markdown 用 # 的数量表示标题级别:

写法级别本站建议用途
# 标题H1整篇文章的主标题,只出现一次
## 标题H2文章的主要章节,例如背景、步骤、总结
### 标题H3H2 下面的子章节,例如某一步的具体说明
#### 标题H4很细的子点,少数情况下使用
##### 标题H5很少使用
###### 标题H6几乎不用

初学者只需要记住一条主线:

  1. H1 写一次,放文章最顶部;
  2. 文章主体用 H2 分大章节;
  3. 每个大章节内部需要继续分层时,用 H3;
  4. H4 只在确实需要第三层结构时使用;
  5. 不要为了字小一点而使用 H4、H5、H6。

完整层级示例:

markdown
# 从零完成一次 VitePress 发布

## 准备工作

### 安装 Node.js

#### 检查系统版本

##### Windows 的补充说明

###### 极少使用的更深层级

## 操作步骤

### 第一步:启动开发服务器

### 第二步:检查页面

## 总结

虽然 Markdown 允许跳级,但不建议从 H1 直接跳到 H3。保持 H1 → H2 → H3 的顺序,页面右侧的本页导航和屏幕阅读器都会更清楚。

VitePress 会为标题自动生成锚点,标题文字也可以成为站内链接的目标。例如本页有 ## 代码块与代码组,就可以链接到 /writing-guide/markdown-basics#代码块与代码组。如果以后修改标题文字,旧锚点可能失效,因此重要链接尽量不要依赖容易变化的标题。

标题常见错误 ​

错误为什么不好改法
文章第一行直接 # 标题,frontmatter 在后面frontmatter 必须最先出现frontmatter 移到文件最顶部
用多个 H1 表示多个章节页面失去唯一主标题主标题保留一个,其余改 H2
用 H5 让字变小标题层级表达结构,不是字号工具用正常 H2/H3,样式交给主题
标题末尾加一堆感叹号导航、搜索和 SEO 标题噪声大用清楚的名词短语

段落、强调与行内格式 ​

段落 ​

段落之间空一行即可:

markdown
这是第一段。它表达一个完整意思。

这是第二段。即使它们在源文件中靠得很近,Markdown 也会用空行判断段落边界。

如果你只在行尾按一次回车,而没有空行,Markdown 通常仍会把两行视为同一段。需要强制换行时,见后文「分隔线、换行、转义与原始 HTML」。

粗体、斜体和删除线 ​

markdown
这是**粗体**,用于强调关键词或结论。

这是*斜体*,适合表示强调语气、作品名或图注。

这是~~删除线~~,适合表示旧说法、作废内容或修订痕迹。

这是 `行内代码`,适合写命令、文件名、字段名和短代码。

显示效果分别是:粗体、斜体、删除线、行内代码。

建议:

  • 一句话里不要连续使用太多粗体,否则重点会消失;
  • 中文正文优先使用 **粗体**,少用 __粗体__;
  • 文件名、命令、字段名优先放进反引号,而不是加粗;
  • 删除线表达作废要谨慎,正式文章里要同时说明原因。

行内代码里有反引号怎么办 ​

如果代码本身包含一个反引号,可以用两个反引号包住它:

markdown
``在 Markdown 中显示 ` 这个字符``

规则是:外层反引号数量要多于内容中最长的连续反引号。平时遇到这种特殊情况不多,记住加一层即可。

空格与强调 ​

下面这些写法可能不会得到你以为的强调效果:

markdown
* 这不太像斜体 *
** 这也不太像粗体 **

星号应紧贴文字:

markdown
*这是斜体*
**这是粗体**

链接:站内链接、锚点与外部链接 ​

三种链接 ​

类型用途示例
站内链接链接到本站另一个页面[发布流程](/writing-guide/publishing)
锚点链接跳到同一页面的某个标题[代码块](#代码块与代码组)
外部链接链接到其他网站[VitePress](https://vitepress.dev/)

本站开启了 cleanUrls: true,所以对外 URL 不写 .html,站内链接也不应该写 .html。链接目标应来自目标页面的 permalink。

假设目标页面 frontmatter 是:

yaml
permalink: /writing-guide/publishing

那么链接应写成:

markdown
[构建、预览、审计与发布完整流程](/writing-guide/publishing)

完整链接示例:

markdown
[Markdown 写作基础](/writing-guide/markdown-basics)

[构建、预览、审计与发布完整流程](/writing-guide/publishing)

[文章示例:项目复盘模板](/posts/技术笔记/项目复盘模板)

[跳到本页的代码块章节](/writing-guide/markdown-basics#代码块与代码组)

[VitePress 官方文档](https://vitepress.dev/)

自动链接:<https://vitepress.dev/>

电子邮件:<mailto:hello@example.com>

对应关系要这样理解:

text
frontmatter 里的 permalink: /writing-guide/publishing
                         ↓
页面访问地址:https://www.baecon.cn/writing-guide/publishing
                         ↓
Markdown 里写:[发布流程](/writing-guide/publishing)

错误示范:

markdown
[发布流程](../writing-guide/publishing.md)

[发布流程](/writing-guide/publishing.html)

[发布流程](docs/writing-guide/publishing.md)

[发布流程](http://localhost:5174/writing-guide/publishing)

问题分别是:

  • 相对 .md 链接在 VitePress 源码中通常可以解析,但本项目有 permalink 重写,链接目标可能与本页假设不同;统一使用对外 permalink 更稳妥;
  • .html 虽然构建目录中可能仍存在对应文件,但不是本站的规范 URL,可能造成重复路径或 canonical 不一致;
  • docs/ 是源码目录,不是站点根目录;
  • localhost 只在你的电脑上有效,部署后会变成错误链接。

推荐统一写成以 / 开头的站内绝对路径:

markdown
[发布流程](/writing-guide/publishing)

这样无论当前页面在哪个目录,链接都能稳定指向公开路由。

外部链接 ​

外部链接写完整协议和域名:

markdown
[Pagefind](https://pagefind.app/)

[VitePress](https://vitepress.dev/)

也可以使用自动链接:

markdown
<https://pagefind.app/>

不要只写 www.example.com,也不要省略 https://。外部链接的文字要说明目标内容,避免只写点击这里。

锚点链接 ​

同页跳转:

markdown
[回到 Frontmatter 章节](#先分清-frontmatter-和正文)

跨页跳转:

markdown
[查看发布页的故障排查](/writing-guide/publishing#常见问题与故障排查)

实际锚点来自标题经过处理后的 ID。最稳妥的做法是:在浏览器打开目标页,点击一次标题旁的链接图标,复制地址栏中 # 后面的内容。不要在没验证的情况下猜复杂锚点。

链接常见错误 ​

错误写法结果正确思路
/writing-guide/publishing.html不是本站规范的 clean URL去掉 .html
../writing-guide/publishing.md源码相对链接可用但不稳定,permalink 重写后会难以追踪优先改用公开 permalink
localhost:5174/...线上访客无法访问你的本机使用站内相对根路径
[点击这里](...)链接文字没有信息量写出目标名称
一个链接同时写路由和 .html可能造成 404、重复页面或 canonical 异常保持 route 与 permalink 一致

图片:位置、引用、替代文本和图注 ​

本站图片放在哪里 ​

普通文章图片统一放在:

text
docs/public/images/posts/<article-slug>/

其中 <article-slug> 建议使用与文章 permalink 最后一段一致的英文短横线命名,例如:

text
文章 permalink:/posts/技术笔记/example-article
图片目录:docs/public/images/posts/example-article/

docs/public/ 是 VitePress 的静态资源根目录。放在 docs/public/images/... 的文件,构建后会出现在站点的 /images/... 路径下:

text
磁盘文件:docs/public/images/posts/example-article/editor-preview.webp
网页地址:/images/posts/example-article/editor-preview.webp

注意:网址中不出现 docs/public。这是初学者最常见的图片 404 原因之一。

插入图片的标准写法 ​

假设图片已经保存为 editor-preview.webp:

markdown
![编辑器中的 Markdown 预览界面](/images/posts/example-article/editor-preview.webp)

*图 1:保存后右侧预览会立即更新。*

逐部分解释:

部分含义
![...]Markdown 图片语法,方括号里是替代文本 alt
编辑器中的 Markdown 预览界面图片读屏文字,也是加载失败时的重要提示
(...)图片 URL,必须以 /images/posts/... 开头
下一段 *图 1:...*可选的图注,用斜体段落表达

为什么图注前要空一行?因为空行会把图注变成独立段落,显示在图片下方;如果紧贴图片不空行,某些 Markdown 解析结果会把它们放在同一段里,导致排版不符合预期。

alt 文本必须写,而且要写清楚 ​

推荐:

markdown
![VitePress 侧边栏中的文章导航](/images/posts/example-article/sidebar.webp)

不推荐:

markdown
![图片](/images/posts/example-article/sidebar.webp)

![截图](/images/posts/example-article/sidebar.webp)

图片和截图不能告诉读屏用户或图片加载失败时的读者:这张图到底展示了什么。好的 alt 应该描述图片传达的信息,而不是简单重复文件名。

本站审计会检查 HTML 中 <img> 是否带有 alt 属性。虽然空泛的 alt 也可能通过机器检查,但不建议敷衍填写。

推荐 WebP,并使用稳定文件名 ​

  • 推荐使用 .webp,在清晰度可接受的前提下体积通常更小;
  • 文件名建议使用小写英文、数字和短横线,例如 editor-preview.webp;
  • 不要在文件名里放空格、中文标点或随意的 最终版-final-真的最终版;
  • 文件扩展名大小写要一致。Windows 本地可能不区分大小写,但 Linux 构建环境通常区分;
  • 图片内容修改后,尽量使用新文件名,避免浏览器或 CDN 继续使用旧缓存。

WebP 是推荐格式,不是绝对强制。已有 JPG/PNG 可以用,但要确认体积和加载体验。

不要使用本地文件系统路径 ​

以下写法全部错误:

markdown
![本地截图](C:\Users\Baecon\Pictures\editor.png)

![相对路径截图](./editor.png)

![源码目录截图](docs/public/images/posts/example-article/editor.webp)

![错误目录截图](/posts/images/editor.webp)

原因:

  1. C:\... 只在你自己的电脑上存在,线上服务器无法访问;
  2. ./editor.png 会相对当前页面路径解析,并不指向 docs/public;
  3. 网页 URL 不应包含 docs/public;
  4. 图片不能放在 docs/posts/ 里当作公开静态资源,docs/posts/ 存放的是 Markdown 文章源文件,不是静态资源目录;
  5. 大小写、扩展名不一致会造成线上 404。

正确写法只有这一类:

markdown
![描述图片内容](/images/posts/example-article/editor-preview.webp)

图片会自动懒加载 ​

本站 docs/.vitepress/config.ts 已全局开启:

ts
markdown: {
  image: {
    lazyLoading: true,
  },
}

所以普通 Markdown 图片不需要你手动添加 loading="lazy"。你只要把图片放在正确目录、用 Markdown 图片语法引用、写清楚 alt 即可。

如果手写原始 HTML <img>,容易漏掉 alt,也可能绕开 Markdown 图片处理逻辑,因此没有特殊必要时不要这样做。

封面图与正文图片:首页卡片如何选择 ​

首页文章卡片按下面的优先级选图:

  1. frontmatter 写了 coverImg:固定使用它。
  2. 没写 coverImg:先随机使用正文中可识别的 Markdown 图片或 HTML <img src="/...">;
  3. 正文也没有图片:从 /home/bg0.webp 到 /home/bg31.webp 随机选一张。

示例(只有需要固定封面时才写):

yaml
coverImg: /images/posts/example-article/cover.webp

它和正文里插入的图片是两件事:

  • coverImg 优先级最高,用于首页卡片、文章 Banner 等位置;
  • 不写 coverImg 时,正文图片会成为首页卡片的随机候选;
  • 正文图片仍然要写在正文中,并且必须写 alt;封面配置不能替代正文内容;
  • 不写 coverImg 不会让卡片缺图,但 SEO 分享图会退回站点默认图。

图片检查清单 ​

  • 文件在 docs/public/images/posts/<article-slug>/ 下;
  • 引用以 /images/posts/<article-slug>/ 开头;
  • 文件名和扩展名与磁盘完全一致;
  • 有具体、可理解的 alt;
  • 可选图注单独空一行,用 *斜体* 写;
  • 没有使用 C:\、./、docs/public 或 docs/posts 作为 URL;
  • 本地和构建后都打开页面确认图片没有 404。

列表:无序、有序、嵌套与任务清单 ​

无序列表 ​

用 -、* 或 + 开头都可以,但同一篇文章建议统一使用 -:

markdown
- 检查 frontmatter
- 检查 H1
- 检查图片

有序列表 ​

需要表达先后顺序时,用数字加点:

markdown
1. 运行 `pnpm install`
2. 运行 `pnpm docs:dev`
3. 打开浏览器检查页面

数字写错时,很多 Markdown 渲染器仍会自动按顺序显示;但为了让源文件也容易阅读,建议按 1、2、3 写。

嵌套列表 ​

嵌套内容向右缩进。为了清楚,建议统一缩进 4 个空格:

markdown
- 准备工作
    1. 安装 Node.js
    2. 安装 pnpm
- 编写文章
    - 填写 frontmatter
    - 写正文
    - 插入图片

嵌套列表前后也要空行,不要在同一行里塞入大量缩写内容。层级越深,手机端越难读,建议最多两层。

任务清单(本站已启用) ​

本站通过 Teek 的 todoPlugin 启用了 Markdown 任务清单。写法是:

markdown
- [ ] 还没有完成
- [x] 已经完成

渲染后会变成带复选框的列表。当前插件生成的是 disabled 复选框,因此它用于展示和阅读,不是让读者在页面上勾选并保存状态。请使用小写 x,并在方括号后保留一个空格。

任务清单适合:

  • 文章内的操作前检查表;
  • 教程的验证步骤;
  • 发布前自检。

它不适合当项目管理数据库。真正的任务状态仍应记录在 Git 平台的 Issue、任务板或你自己的任务工具中。

列表常见错误 ​

错误结果修改方法
列表前没有空行列表可能被当成上一段的一部分列表前后留空行
嵌套缩进有的 2 格、有的 6 格层级错乱统一缩进 4 格
同一篇文章混用 -、*、+风格不统一统一用 -
写了 - [x] 但页面没有复选框本站只识别小写 x 和 [ ] 后一个空格统一使用 - [ ] / - [x],并检查空格

引用与表格 ​

引用 ​

在行首使用 >:

markdown
> 这是一段引用,适合引用别人的观点、官方说明或需要突出显示的提示。

> 引用中也可以放列表:
>
> - 第一项
> - 第二项

> 第一层引用
>
> > 嵌套的第二层引用

引用块里可以用 Markdown,但仍要遵守空行和闭合规则。引用不是容器,不会自动出现彩色背景;需要彩色提示时,使用后面的 VitePress 容器。

表格 ​

标准表格:

markdown
| 检查项 | 说明 | 状态 |
|---|---|---|
| Node.js | 是否满足版本要求 | 待检查 |
| pnpm | 是否能执行项目脚本 | 待检查 |
| 图片 | 路径和 alt 是否正确 | 待检查 |

对齐方式由分隔行控制:

markdown
| 左对齐 | 居中 | 右对齐 |
| :--- | :---: | ---: |
| 文本 | 文本 | 数字 |

注意事项:

  • 表格前必须空一行,表格后也建议空一行;
  • 第二行是表头分隔行,不能省略;
  • 列数不必在源文件中完全对齐,但保持整齐更易维护;
  • 单元格内如果要显示竖线 |,使用 \| 转义;
  • 表格适合短文本对照,不适合塞入很长的段落或复杂代码;
  • 手机屏幕较窄,列太多时读者需要横向滚动,尽量控制在 2~4 列。

单元格转义示例:

markdown
| 写法 | 显示结果 |
|---|---|
| `a \| b` | 显示一个竖线 |

代码块与代码组 ​

语言标签必须写 ​

围栏代码块使用三个反引号开头,后面紧跟语言名称:

markdown
```bash
pnpm docs:dev
```

这里的 bash 是语言标签。本站规定代码块必须写语言标签;即使是普通文字,也写成 text,不要留空。VitePress 的代码高亮器需要语言信息,代码组也需要它来生成标签和图标。

常用语言标签:

内容推荐标签
终端命令bash
普通文本、目录树text
TypeScriptts
JavaScriptjs
JSONjson
Markdown 示例markdown
YAML / frontmatteryaml
HTMLhtml
CSScss
Vuevue

不写语言标签通常不会让构建失败,但会失去正确高亮,也不符合本站写作规范。

行号已经全局开启 ​

docs/.vitepress/config.ts 中配置了:

ts
markdown: {
  lineNumbers: true,
}

所以代码块会自动显示行号,你不需要在每个代码块额外写开关。语言标签必须与内容匹配,否则行号虽然会出现,代码却是错误的配色。

行号是展示辅助,不会改变代码内容,也不应该被当成复制后需要删除的文本。

代码块标题 ​

在语言标签后面加方括号,可以指定代码块标题:

markdown
```ts [docs/.vitepress/config.ts]
export default {
  cleanUrls: true,
}
```

标题会显示在代码块上方,方便读者知道文件位置。标题是标签,不是文件系统路径;不要把它写成 C:\...。

行高亮 ​

在语言标签后加 {行号},可以高亮指定行:

markdown
```ts{2,5-7} [docs/.vitepress/config.ts]
import { defineConfig } from "vitepress";

export default defineConfig({
  cleanUrls: true,
  markdown: {
    lineNumbers: true,
    image: { lazyLoading: true },
  },
});
```

解释:

  • {2} 表示高亮第 2 行;
  • {5-7} 表示高亮第 5 到第 7 行;
  • {1,3-4} 表示第 1 行和第 3 到第 4 行;
  • 行高亮只影响显示,不改变代码;
  • 行号从 1 开始,按代码块内部的实际行数计算。

当需要同时写标题和行高亮时,行高亮放在语言标签后,标题放在最后:

text
```ts{2,5-7} [docs/.vitepress/config.ts]

bash、ts、json、markdown 完整示例 ​

下面四个代码块展示常见语言标签和标题写法:

markdown
```bash [安装依赖并启动开发服务器]
pnpm install
pnpm docs:dev
```

```ts [hello.ts]
const site: string = "Baecon 的博客";
console.log(site);
```

```json [package.json]
{
  "scripts": {
    "docs:build": "vitepress build docs"
  }
}
```

```markdown [文章片段]
## 小节标题

这是一段正文。
```

代码组 ​

代码组用于把同一任务的不同语言、不同工具或不同系统写法放在一组标签页里。本站已经配置 ::: code-group 和代码组图标能力。

完整示例:

markdown
::: code-group

```bash [bash]
pnpm docs:dev
```

```ts [config.ts]
export default {
  cleanUrls: true,
};
```

```json [package.json]
{
  "scripts": {
    "docs:dev": "vitepress dev docs"
  }
}
```

```markdown [文章片段]
# 示例标题

正文。
```

:::

规则:

  1. 用 ::: code-group 开始,用单独的 ::: 结束;
  2. 每一段代码仍然必须是完整的围栏代码块;
  3. 方括号里的文字会成为标签页标题;
  4. 建议给每个标签写清楚名称,例如 bash、config.ts、package.json;
  5. 代码组内各代码块之间空一行;
  6. 第一个代码块默认选中;
  7. 代码组图标插件会根据标签匹配图标,但不要为了图标牺牲标签的可读性。

常见错误:

  • 把 ::: code-group 写成 :::code-group 或拼错;
  • 忘记最后一行 :::;
  • 代码块没有语言标签;
  • 代码块标题用了中文方括号;
  • 在一个代码组里塞入完全不相关的内容。

代码块包含反引号时 ​

如果代码内容本身就包含三个反引号,外层围栏要用更多反引号:

markdown
````markdown
```bash
pnpm docs:build
```
````

原则很简单:外层围栏的反引号数量必须多于内部。写完后查看渲染结果,确认代码块没有提前结束。

VitePress 容器 ​

本站 docs/.vitepress/config.ts 已配置中文容器标签:

容器类型中文标题适用场景
tip提示建议、技巧、补充说明
info信息背景知识、前置条件
warning警告容易出错但可恢复的操作
danger危险删除、覆盖、泄露密钥等高风险操作
details详细信息可折叠的长说明、补充材料

五种容器的完整写法 ​

markdown
::: tip 提示
这里写一条实用建议。
:::

::: info 信息
这里写背景信息或阅读前提。
:::

::: warning 警告
这里写容易犯的错误。

1. 先备份。
2. 再执行。

```bash
pnpm docs:build
```

:::

::: danger 危险
这里写不可逆操作或安全风险,例如不要泄露 API Token。
:::

::: details 详细信息
点击标题展开。这里适合放较长解释、表格、链接或排查步骤。
:::

容器内的内容仍然是 Markdown:可以放列表、链接、行内代码、代码块和表格。上面 warning 示例就是列表加代码块的嵌套内容。

为什么标题要写中文 ​

配置里的默认标签已经是中文:

ts
container: {
  tipLabel: "提示",
  warningLabel: "警告",
  dangerLabel: "危险",
  infoLabel: "信息",
  detailsLabel: "详细信息",
}

因此下面两种写法都可以显示中文提示:

markdown
::: tip
默认显示为「提示」。
:::

::: tip 提示
显式写标题,仍然是「提示」。
:::

本站统一写成 ::: tip 提示 这种显式形式,复制到其他地方时更清楚。容器类型单词保留英文,不要把 tip 改成中文。

容器常见错误 ​

错误结果修改方法
只写 ::: tip,最后忘记 :::后续内容全部落入容器,页面结构异常补上结束行
开始和结束冒号数量不一致容器无法正确闭合前后都用三个冒号
::: 前后没有空行部分 Markdown 内容可能解析不正确容器前后各留空行
在容器里再写 H1页面出现多个 H1容器内只用 H2 以下标题
使用未配置的容器类型可能只显示普通块或原始文字只用 tip、info、warning、danger、details

details 是折叠的 ​

::: details 详细信息 会渲染成可折叠区域,默认收起,点击标题展开。它适合放长日志、可选阅读的背景材料和故障排查细节。

不要把最重要的结论藏在 details 里。读者可能不会展开,文章关键信息仍然应该放在普通正文。

时间线 ​

本站已启用 vitepress-markdown-timeline 插件,并在主题中加载了对应样式。语法是每个日期一个独立区块:

markdown
::: timeline 2026-11-08
**发布写作指南**

- 完成 Markdown 写作基础页
- 补充代码组示例
- 检查所有站内链接

:::

::: timeline 2026-11-07
**完成初稿**

正文可以使用普通 Markdown,例如列表、链接和 `行内代码`。

:::

规则和注意点:

  1. ::: timeline 2026-11-08 中,日期是时间线标签,建议统一使用 YYYY-MM-DD;
  2. 每个日期单独开一个 ::: timeline 日期 区块;
  3. 每个区块都用单独的 ::: 结束;
  4. 日期区块内部可以写段落、列表、加粗、链接等普通 Markdown;
  5. 按你希望阅读的顺序组织时间线;
  6. 时间线内部不要再放 H1;
  7. 不要把多个日期塞进同一个 timeline 容器。

如果时间线没有样式,先检查开发服务器是否重启,以及 docs/.vitepress/theme/index.ts 是否正常加载了时间线 CSS。普通内容写作者通常只需要正确写 Markdown,不需要改插件配置。

分隔线、换行、转义与原始 HTML ​

分隔线 ​

正文中单独一行写三个或更多短横线,会生成一条横向分隔线:

markdown
第一段内容。

---

第二段内容。

分隔线适合分隔两个明显不同的部分,不要每两段就放一条。文章末尾也不要再额外放一条分隔线。

注意:文件最顶部的 --- 属于 frontmatter,不是正文分隔线。在正文里使用分隔线时,它应该出现在 H1 之后。

换行 ​

普通段落中直接按一次回车,渲染后可能仍然是同一段;用空行分隔才会变成两个段落。

如果需要在一个段落内部强制换行,可以在第一行末尾输入两个空格或反斜杠,然后换行:

markdown
第一行(行尾是反斜杠)\
第二行强制从这里开始

如果使用两个空格,空格是语法的一部分,很多编辑器会保存但不显示;如果编辑器会清理行尾空白,可以用反斜杠。保存后最好在浏览器里确认效果。

正文排版优先用空行分段落;只有在地址、诗歌、短句等确实需要强制换行时,才使用行尾双空格。原始 HTML 的 <br> 也能换行,但本站不建议为了普通排版引入 HTML。

转义 Markdown 特殊字符 ​

反斜杠 \ 可以让某些 Markdown 字符按普通文字显示:

markdown
\*这不是斜体\*

\# 这不是标题

\[这不是链接\](https://example.com)

一行里显示两个星号:\*\*

如果只是想在正文里展示一段 Markdown 语法,优先使用行内代码,清晰又不容易出错:

markdown
输入 `**粗体**` 会显示语法本身,而不是变粗。

常见需要转义的字符包括:

字符不转义的效果转义写法
*斜体或列表\*
_斜体\_
#标题\#
[ ]链接或图片标记\[ \]
`行内代码边界用更多反引号包住

路径、命令、JSON 和代码优先放进代码块或行内代码,而不是在正文里手动堆反斜杠。

原始 HTML 要谨慎 ​

VitePress 的 Markdown 可以渲染一部分原始 HTML,例如:

html
<span>这是一段 HTML</span>

但本站建议:能用 Markdown 表达的内容,就不要手写 HTML。

原因包括:

  • 原始 HTML 可读性差,初学者容易漏闭合标签;
  • 手写 <img> 容易漏掉 alt;
  • 原始 HTML 可能绕开 Markdown 图片懒加载等处理;
  • 复杂的 HTML、Vue 组件和脚本需要测试构建与暗色模式;
  • 不想暴露的内部信息不要写进 HTML 注释,注释仍可能出现在构建产物里。

除非确有特殊展示需求,否则优先使用 Markdown、表格、代码块或图片。不要手写 <script>,不要把密钥、Token 或内部地址写进页面。

摘要标记与首页摘要 ​

本站优先使用 description ​

文章摘要的主要来源是 frontmatter 的 description:

yaml
description: 一句话说明读者读完能得到什么。

description 会用于页面 SEO 描述、分享信息和首页文章卡片。写文章时应主动把它写完整,不要指望主题从正文里随便截一段。

<!-- more --> 是可选标记 ​

<!-- more --> 是 HTML 注释形式的分隔标记,阅读页面时看不到它,但它可以提示主题在正文的哪个位置截断摘要。

可选写法:

markdown
# 文章标题

这里是文章导语,说明读者为什么要继续读下去。

<!-- more -->

## 背景

这里开始是正文。

在本站当前写作规范中:

  • description 是主摘要来源;
  • <!-- more --> 是次要、可选的手动截断标记;
  • 没有 <!-- more --> 不会阻止文章构建或发布;
  • 不要依赖这个标记代替 description;
  • 一篇文章最多放一个,位置通常在导语之后、正文主体之前。

摘要常见错误 ​

做法问题
只写 <!-- more -->,不写 description首页、SEO 和分享缺少稳定摘要
把 <!-- more --> 放进 frontmatter 的两条 --- 之间它不是 YAML 字段,位置错误
文章里放多个 <!-- more -->截断位置不可预测,维护困难
摘要和正文第一段一模一样信息重复,首页阅读体验差

完整文章骨架 ​

下面是一份可以直接复制后修改的完整文章骨架。复制后至少要改标题、描述、日期、permalink、分类、标签和图片文件名。

markdown
---
title: 用一个可读的标题说明文章内容
description: 一句话说明读者读完能得到什么,建议 50–150 个中文字符。
permalink: /posts/技术笔记/example-article
categories:
  - 技术笔记
tags:
  - VitePress
  - Markdown
article: true
sidebar: true
pagefind-indexed: true
comment: true
---

# 用一个可读的标题说明文章内容

> 一段导语:告诉读者这篇文章解决什么问题,以及阅读前需要知道什么。

## 这篇文章适合谁

- 已经会基础 Markdown 的读者
- 第一次在本站写文章的读者

## 背景与目标

说明问题背景、目标和最终要得到的结果。

## 准备工作

开始前请确认:

1. 已安装 Node.js 和 pnpm;
2. 已阅读[构建、预览、审计与发布完整流程](/writing-guide/publishing)。

## 操作步骤

### 第 1 步:创建文章文件

在 `docs/posts/技术笔记/` 下创建 `01.example-article.md`。

### 第 2 步:填写 frontmatter

把上面的元数据改成你的文章信息,并确保 `permalink` 唯一。

### 第 3 步:写正文并插入图片

![编辑器中的 Markdown 预览界面](/images/posts/example-article/editor-preview.webp)

*图 1:图片下方用斜体写图注,图片的 alt 必须描述内容。*

### 第 4 步:验证

```bash
pnpm docs:dev
```

打开 `/writing-guide/publishing` 查看发布流程。

::: tip 提示
示例路径中的 `example-article` 和图片文件名必须换成你的真实文件。
:::

## 常见问题

### 图片显示 404 怎么办?

检查文件是否放在 `docs/public/images/posts/example-article/`,以及 URL 是否以 `/images/` 开头。

## 总结

用两三句话回顾读者已经完成的事情,并给出下一步。

## 参考资料

- [VitePress 官方文档](https://vitepress.dev/)
- [Markdown 基础](/writing-guide/markdown-basics)

使用这个骨架时的顺序:

  1. 先把 frontmatter 的占位内容换掉;
  2. 确认 permalink 与文件 slug 对应且全站唯一;
  3. 保留且只保留一个 H1;
  4. 按 H2、H3 写正文;
  5. 把示例图片换成真实存在的 WebP;
  6. 删除不需要的章节;
  7. 按下一节检查未启用扩展;
  8. 按最后的清单逐项自检。

本站未启用的扩展 ​

本站确实启用了 VitePress 原生容器、代码组、vitepress-markdown-timeline 时间线和代码组图标。但以下能力没有启用:

  • Mermaid 图表没有启用。写 ```mermaid 不会自动变成流程图或时序图,只会当作代码内容处理;
  • KaTeX / 数学公式没有启用。$...$ 或 $$...$$ 不会自动排版成数学公式;
  • 除本页说明的容器、代码组、时间线、Pagefind 搜索、RSS 和 sitemap 外,不要假设其他插件已经启用。

需要图表或公式时,先把问题改成表格、文字步骤或静态图片,并遵守图片 alt 规则。若未来要正式增加 Mermaid 或数学公式,应先由站点维护者改配置、安装依赖、验证构建和审计,不能只在文章里写一段语法就宣称可用。

发布前写作检查清单 ​

下面使用 - [ ] 任务清单语法,会渲染为禁用复选框,适合清单展示;它不是交互式任务管理工具。

  • Frontmatter 从文件第一行开始,并且只有一个区块;
  • title、description、date、permalink、categories、tags 已填写;
  • permalink 以 /posts/... 开头且全站唯一;
  • 正文有且只有一个 H1;
  • 主要章节使用 H2,子章节使用 H3,没有为了字号乱跳级;
  • 标题、段落、列表、表格、代码块和容器前后有空行;
  • 站内链接优先使用公开 permalink;没有使用 docs/ 源码路径或 localhost,也没有把 .html 当作规范地址;
  • 图片位于 docs/public/images/posts/<article-slug>/;
  • 图片引用以 /images/posts/<article-slug>/ 开头;
  • 每张图片都有具体 alt,推荐 WebP,图注使用独立斜体段落;
  • 没有使用 C:\ 或本地磁盘路径;
  • 代码块都写了正确语言标签;
  • 需要行高亮或标题时,语法写在语言标签后面;
  • 代码组有开始和结束 :::,每个代码块都有标签;
  • 容器使用 tip、info、warning、danger、details 五种类型;
  • 时间线每个日期独立成块并正确闭合;
  • 正文没有误用第二个 frontmatter 分隔线;
  • 摘要优先写在 description,<!-- more --> 没有被当成必需项;
  • 没有依赖未启用的 Mermaid 或 KaTeX;
  • 最后运行 pnpm docs:build、pnpm docs:audit 并预览构建产物。

下一步请阅读构建、预览、审计与发布完整流程,把文章真正发布到线上。

最后更新于: