Markdown Front Matter:YAML 头信息完全指南
你打开一个 Markdown 文件,发现顶部有一段被 --- 包裹的内容——那就是 front matter。它不显示在页面上,却在背后默默控制着文章的标题、日期、标签、模板这些重要信息。
如果你用 Jekyll、Hugo 搭建过博客,或者在 Obsidian 里管理笔记,front matter 几乎绕不开。这篇文章会把 YAML 头信息的语法、写法、各个工具的差异,以及我自己踩过的坑,一次性讲清楚。对 Markdown 语法有基本了解就能跟得上。
什么是 Front Matter
Front matter 就是 Markdown 文件最开头的一段元数据(metadata),用三个短横线 --- 作为开始和结束标记,中间写 YAML 格式的键值对。它告诉处理这个文件的工具:"嘿,这篇文章的标题是这个,日期是那个,分类是这些。"
一个最简单的例子:
---
title: 我的第一篇文章
date: 2026-05-13
---
正文内容从这里开始...有几个硬性规则:front matter 必须是文件的第一行内容(前面不能有空行),两个 --- 之间的内容必须是合法的 YAML,而且结尾的 --- 不能省略。
有一点容易混淆——--- 在 Markdown 正文里表示水平分隔线,但出现在文件最顶部时,所有主流解析器都把它识别为 front matter 的起始标记,不会当作分隔线处理。
YAML 语法速查
Front matter 里的内容遵循 YAML 语法规范。如果你之前没接触过 YAML,这里过一遍核心写法就够了。
基本键值对
title: 我的第一篇文章
author: 张三
draft: false
views: 1024冒号后面加一个空格,值就直接写在后面。布尔值用 true / false,数字直接写。
一个很容易踩的坑:如果你的值里包含冒号 : 或者井号 #,必须加引号,否则解析器会报错。比如:
title: "入门指南:从零开始"
description: "技巧 #1:保持简洁"不加引号的话,: 后面的内容会被当作新的键值对,# 后面的内容会被当作注释忽略掉。
列表
两种写法都行,看你喜欢哪种:
行内写法:
tags: [markdown, yaml, 教程]多行写法:
tags:
- markdown
- yaml
- 教程嵌套对象
seo:
title: "SEO 标题"
description: "页面描述"
image: "/images/cover.png"嵌套层级用两个空格缩进。说实话,我以前习惯用 Tab 键缩进,结果 Jekyll 构建直接报错——YAML 规范只认空格,Tab 会导致解析失败。这是新手最常见的错误之一。
日期格式
推荐用 ISO 8601 格式:
date: 2026-05-13
lastmod: 2026-05-13T14:30:00+08:00有些工具只要日期部分就行,有些要求完整的时间戳。具体看你所用工具的文档。
常用字段一览
不同工具支持的字段不完全一样,但下面这些是"通用款",大部分平台都认:
| 字段 | 说明 | 典型值 |
|---|---|---|
title | 文章标题 | title: 我的第一篇文章 |
date | 发布日期 | date: 2026-05-13 |
lastmod | 最后修改日期 | lastmod: 2026-05-13 |
author | 作者 | author: 张三 |
tags | 标签列表 | tags: [markdown, yaml] |
categories | 分类 | categories: [教程] |
description | 页面描述(SEO) | description: 一篇关于... |
draft | 是否为草稿 | draft: true |
layout | 使用的模板 | layout: post |
slug | 自定义 URL | slug: my-first-post |
weight | 排序权重 | weight: 10 |
这些字段名是约定俗成的,不是 YAML 标准定义的。换个说法,你可以写 banana: true,但不会有任何工具认识这个字段——它只会被静默忽略。
不同工具的差异对比
这是我觉得写 front matter 时最容易让人困惑的部分:同一个字段,在不同工具里行为不一样。我对比了几个主流工具:
| 特性 | Jekyll | Hugo | VitePress | Obsidian |
|---|---|---|---|---|
| 格式支持 | YAML | YAML / TOML / JSON | YAML | YAML |
| 空的 front matter | ✅ 会处理该文件 | ✅ | ✅ | ✅ |
tags 用于分类 | ✅ | ✅ | ❌ 需自行处理 | ✅ Dataview 可查询 |
draft: true 跳过构建 | ❌ 默认不跳过 | ✅ 生产构建跳过 | ❌ 需配置 | ❌ 仅显示用途 |
| 嵌套对象 | ✅ | ✅ | ✅ | ⚠️ 部分插件支持 |
| 自定义字段 | ✅ Liquid 模板调用 | ✅ .Params 访问 | ✅ $frontmatter | ✅ Dataview 查询 |
| TOML 支持 | ❌ | ✅ 用 +++ 分隔 | ❌ | ❌ |
拿 draft 字段举个例子:在 Hugo 里,draft: true 的文章在生产构建时会被自动跳过,非常方便;但在 Jekyll 里,默认情况下草稿文章也会被发布出去,除非你手动加 --drafts 参数或者在 _drafts 目录下管理。
这些差异是我在同时维护一个 Jekyll 博客和一个 Hugo 文档站时总结出来的,踩了不少坑才搞清楚。
一个完整的 Front Matter 示例
下面是一个接近实际项目会用到的配置:
---
title: "Markdown Front Matter 完全指南"
date: 2026-05-13T10:00:00+08:00
author: "张三"
tags:
- markdown
- yaml
- 教程
categories:
- 技术文档
description: "从 YAML 语法到工具差异,一篇搞懂 Markdown Front Matter 的方方面面。"
draft: false
slug: markdown-front-matter-guide
seo:
title: "Markdown Front Matter & YAML 头信息"
description: "什么是 front matter,怎么写,各工具有什么区别。"
image: "/images/frontmatter-cover.png"
---
## 正文从这里开始
你的文章内容...常见问题排查
写 front matter 时遇到问题,大概率是以下几种情况:
YAML 解析错误
症状:工具报错说 front matter 无效,或者字段值不是你期望的。
排查思路:
- 缩进是否用了空格——Tab 会导致解析失败,这是排名第一的原因
- 冒号后面有没有空格——
title:我的文章(错误)vstitle: 我的文章(正确) - 特殊字符是否加了引号——包含
:#[]的值需要用引号包裹 - 列表缩进是否对齐——多行列表的
-前面缩进要一致
Front Matter 不生效
症状:明明写了 front matter,但工具好像没识别到。
常见原因:
- front matter 前面有空行或 BOM 字符(文件编码问题)
- 使用了
...而不是---作为结束标记(部分工具不支持) - 文件后缀不对(比如 Jekyll 要求
.md或.html)
值被错误解析
version: 1.0你以为 version 是字符串 "1.0",但 YAML 解析器会把它当作浮点数 1.0。解决方法:加引号。
version: "1.0"类似的情况还有 true/false/yes/no/on/off——YAML 会把这些全部解析为布尔值。如果你的值恰好是这些词(比如标签 tags: [on, off]),记得加引号。
用代码解析 Front Matter
有时候你需要批量处理 Markdown 文件,提取 front matter 里的元数据。JavaScript 生态里最常用的库是 gray-matter:
const matter = require('gray-matter');
const file = matter.read('./article.md');
console.log(file.data); // { title: '...', date: '...', tags: [...] }
console.log(file.content); // '---' 下面的正文内容Python 用户可以用 python-frontmatter:
import frontmatter
with open('article.md') as f:
post = frontmatter.load(f)
print(post['title']) # 文章标题
print(post.metadata) # 完整的 front matter 字典
print(post.content) # 正文内容两个库的思路一样:把 Markdown 文件拆成 data(元数据)和 content(正文)两部分,分别处理。