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自定义 URLslug: my-first-post
weight排序权重weight: 10

这些字段名是约定俗成的,不是 YAML 标准定义的。换个说法,你可以写 banana: true,但不会有任何工具认识这个字段——它只会被静默忽略。

不同工具的差异对比

这是我觉得写 front matter 时最容易让人困惑的部分:同一个字段,在不同工具里行为不一样。我对比了几个主流工具:

特性JekyllHugoVitePressObsidian
格式支持YAMLYAML / TOML / JSONYAMLYAML
空的 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 无效,或者字段值不是你期望的。

排查思路:

  1. 缩进是否用了空格——Tab 会导致解析失败,这是排名第一的原因
  2. 冒号后面有没有空格——title:我的文章(错误)vs title: 我的文章(正确)
  3. 特殊字符是否加了引号——包含 : # [] 的值需要用引号包裹
  4. 列表缩进是否对齐——多行列表的 - 前面缩进要一致

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(正文)两部分,分别处理。

参考来源