Front matter in site generators vs plain notes
Bobby Huang ·
A static site generator reads a few front matter fields to decide a page's URL, layout, sort order and whether it gets published, such as date, draft, layout, permalink and tags. People and agents read other fields, like status, owner and a handoff path. One header can carry both if you keep dates as YYYY-MM-DD, booleans as true or false, lists as YAML lists, and note fields flat and clearly named. Check your generator's docs for the exact field names, because they differ.
Key takeaways
- A site build reads front matter to set the URL, layout, publish state and sort order of each page.
- Note fields such as status, owner and handoff are for people and agents, and a site build usually ignores keys it does not use.
- Some generators reserve their own field names, so check your generator's docs before adding note fields.
- The Go-based yq, version 4, can list keys, read draft, check that date is a timestamp and print the file with draft flipped.
- Sashmark is in development and not released; its Frontmatter Table is planned for v1.
A Markdown file with a YAML header can have two very different readers. One is a site build. The other is you, a teammate, or the next agent run that opens the file to see where the work stands. If your agent-written notes might feed a website later, or your site posts also get read as working notes, you want one header that serves both without a fight.
This post covers how front matter in a static site generator differs from front matter in plain notes, which fields each reader cares about, and a short recipe for checking a header from the terminal. If you need the basics first, start with what front matter is.
The short version: let the build have its fields, let the notes have theirs, and write both in plain, portable YAML.
Two readers, one header
A site build reads front matter to make decisions. It looks for a few keys that tell it what URL the page gets, which layout wraps it, whether it gets published at all, and where it sorts in a list. Everything else in the header is, from the build's point of view, extra.
People and agents read the header differently. They want to know the status of the work, who owns it, and where the handoff note lives. A build usually has no use for those fields unless a template reads them, but they are often the reason the file exists.
Plain notes only have the second kind of reader: people, tools and agents. Once a note becomes a page, it picks up the first kind too, and the header has to make sense to both.
What a front matter static site generator looks for
Field names differ between generators, so check the docs for yours. Here is what three of them say about the fields their builds read.
| Field | What it controls | Generator |
|---|---|---|
date, draft, title, weight |
Hugo's most common fields | Hugo |
params |
Holds custom fields, since Hugo's listed field names are reserved | Hugo |
layout |
Which layout wraps the page | Jekyll, Eleventy |
permalink |
The page's URL | Jekyll, Eleventy |
published |
Set to false to leave a post out of the build |
Jekyll |
date, categories, tags |
Extra fields that posts take | Jekyll |
tags |
Marks the page as part of a collection | Eleventy |
date |
Overrides the file date for sorting | Eleventy |
eleventyExcludeFromCollections |
true leaves the page out of every collection; the page itself is still built |
Eleventy |
A few format rules come with these. Hugo accepts front matter as JSON, TOML or YAML and tells which one you used by the delimiters. Jekyll wants front matter to be the first thing in the file, as valid YAML between triple-dashed lines. If your header breaks, the YAML front matter rules post shows how to find and fix it.
What notes carry that a site ignores
Notes written by or for agents tend to carry working fields: status, owner, handoff. These tell the next reader what state the work is in and where to pick up. The post on status, date and owner fields covers which ones are worth keeping.
A build usually ignores keys it does not use, so these fields can sit in the same header as title and date. The one rule to plan around is Hugo's: its listed field names are reserved, and custom fields belong under the params key. If the file is built by Hugo, put note fields there, or at least make sure none of them reuse a reserved name.
Check one header with yq
The Go-based yq, version 4, can read front matter straight out of a Markdown file with --front-matter=extract, and print the file with a changed header with --front-matter=process. Here is a sample post.md:
---
title: Settings page dark theme
date: 2026-10-19
draft: true
tags: [settings, ui]
status: in-review
owner: Jane Doe
handoff: plans/settings-handoff.md
---
# Settings page dark theme
Notes for the next agent run.
Run each check from the folder that holds the file.
List every key in the header.
yq --front-matter=extract 'keys' post.md- title - date - draft - tags - status - owner - handoffList the keys that fall outside your site's set. Here the site set is
title,date,draftandtags, so what is left are the note fields.yq --front-matter=extract 'keys - ["title", "date", "draft", "tags"]' post.md- status - owner - handoffRead the
draftflag.yq --front-matter=extract '.draft' post.mdtrueCheck that
dateis read as a timestamp and not as a string.yq --front-matter=extract '.date | tag' post.md!!timestampRead a field that may be missing, with a default.
yq --front-matter=extract '.slug // "(none)"' post.md(none)Flip
drafttofalse. With--front-matter=process, yq prints the whole file with the header changed and the body left as it was.yq --front-matter=process '.draft = false' post.md--- title: Settings page dark theme date: 2026-10-19 draft: false tags: [settings, ui] status: in-review owner: Jane Doe handoff: plans/settings-handoff.md --- # Settings page dark theme Notes for the next agent run.
Step 2 is the useful one when a note is about to become a page. It shows which fields fall outside the set you chose. Check each one against your generator's docs and your templates, since a template can read a custom field too, then decide whether it stays, moves under params, or goes.
Portable habits for a shared header
These keep one header readable by a build, a person and an agent:
- Dates as YYYY-MM-DD. No quotes, no time unless you need one. Step 4 above shows yq reading that form as a timestamp.
- Booleans as
trueorfalse. Notyes,no,onor a quoted string. For when to quote a value, see quoting in YAML front matter. - Lists as YAML lists.
tags: [settings, ui]or one item per line with a dash. Not a comma-separated string. - Note fields flat and clearly named.
owner: Jane Doereads better to an agent than a nested block, and a plain name is less likely to clash with a generator's reserved field. If Hugo builds the file, put them underparamsinstead. - Nothing generator-specific unless that generator builds the file. A
weightoreleventyExcludeFromCollectionsin a plain note is noise to every other reader.
Where Sashmark fits
When one header carries both site fields and note fields, the hardest part is seeing all of it at once. A good reader should show the whole header as a small table, so draft and date sit right next to status and owner and both kinds are easy to scan. The post on reading YAML front matter as a table shows why that view helps.
Sashmark is a Markdown reader and editor for people whose AI agents write Markdown, being built for Mac, Windows and Linux. It is in development and has not been released, and the app has no AI features of its own. Sashmark is being built for this: its Frontmatter Table is planned for v1, as listed on the planned features page. The roadmap shows where it stands.
Sashmark is in development. See what it is at sashmark.com.
Questions
- Will a static site generator break if my front matter has extra note fields?
- A build usually ignores keys it does not use, so fields like status or owner tend to pass through. Some generators reserve their own field names and want custom fields kept in a separate place, so check the front matter docs for your generator.
- Which date format works for both a site build and a plain note?
- Write dates as YYYY-MM-DD with no quotes. The yq check in this post reads that form as a timestamp, it still reads cleanly as a date to a person or an agent, and your generator's docs say how it reads dates.
- How do I keep a post out of the build without deleting it?
- It depends on the generator. Some document a field that leaves a post out of the build. Others have a field that only keeps a page out of lists, and the page still gets built. The table in this post shows which field each generator documents; check its docs before you rely on one.