How to extract YAML frontmatter

By

Split YAML frontmatter from a Markdown file in the browser. The mapping becomes JSON, a timestamp becomes an ISO string, and the body is left as written.

Free toolThis tutorial uses the YAML Frontmatter Extractor. It runs in your browser, so open it in another tab and follow along.

A Markdown file for a blog often starts with a small block of data. The title, the date, and the tags live there, and the article lives under them. Jekyll called that block frontmatter. Hugo and Astro content collections use the same shape.

The file starts with a line that is exactly ---. YAML comes next. A later line that is exactly --- closes the block. Everything after that line is the body. The YAML frontmatter extractor splits the two and prints the mapping as JSON. The file stays in the browser.

How YAML frontmatter is split from the bodyThe file must start with a line of three hyphens. YAML 1.1 is parsed as a mapping. A timestamp becomes an ISO string. The text after the closing fence is the body.NoYesFile starts with ---YAML 1.1 mappingIs it a mapping?Show the errorJSON, with dates asISO stringsBody after theclosing fence

Why the fence is the first line

The opening fence is not a search. It is the first line. A title, a blank line, or a comment before it means this file has no frontmatter. Editors sometimes add a blank line when you paste. The page then says the opening fence is missing, which is the right answer. Move the --- back to line 1.

The closing fence is the first later line whose text is exactly three hyphens. Spaces after the hyphens do not count. A line of three dots does not count. YAML allows ... as a document end marker. This page does not, because the generators that popularized frontmatter close with ---.

The YAML between the fences is parsed as YAML 1.1. That is the schema Jekyll and the usual Markdown frontmatter use. In that schema an unquoted date is a timestamp, not a string. The page turns the timestamp into an ISO string with toISOString(), and it says so once. A date you wrap in quotes stays a string, because the quotes opt out of the timestamp rule.

The value has to be a mapping. A list at the top is refused. An empty pair of fences is an empty mapping, and the JSON is {}.

Extract the sample

Open the YAML frontmatter extractor and click Load sample. The sample is a short post:

---
title: How DNS works
date: 2026-11-05
tags:
  - dns
  - http
draft: false
---
The resolver asks a root server first.

The page prints:

Keys: 4
title
date
tags
draft

JSON:
{
  "title": "How DNS works",
  "date": "2026-11-05T00:00:00.000Z",
  "tags": [
    "dns",
    "http"
  ],
  "draft": false
}

Body:
The resolver asks a root server first.

Four keys, in the order YAML gave them. title is a string. draft is a boolean, not the string "false". tags is an array of two strings. The body keeps its trailing newline. It is not trimmed, and it is not passed through a Markdown renderer.

The date needs a closer look. The source says 2026-11-05, with no time and no quotes. YAML 1.1 reads that as a timestamp at midnight UTC. toISOString() then writes 2026-11-05T00:00:00.000Z. The note is: A YAML timestamp was written as an ISO string. If you quote the date, "2026-11-05", the JSON keeps the string 2026-11-05 and the note does not appear.

A timestamp that already has a time is the same conversion. date: 2026-11-05T04:47:20Z prints:

Keys: 1
date

JSON:
{
  "date": "2026-11-05T04:47:20.000Z"
}

Body:
Body

The source had no fraction. toISOString() writes .000. The instant is the same. A quoted date does not go through that path. date: "2026-11-05" prints "date": "2026-11-05" and adds no note.

That difference matters when you compare this output with a file on disk. A generator may keep the date as a date object in memory and format it in a local timezone when it prints a page. The JSON here is always UTC. A date-only value is midnight UTC, which is the previous evening in timezones behind UTC. If your dates are shifting by one day, this is the place to look.

A list, a missing fence, and a YAML error

A file that starts with a list is valid YAML and invalid frontmatter:

---
- dns
- http
---

The page says:

Frontmatter has to be a mapping. This document is a list.

Frontmatter is a set of named fields. A bare list has no names, so there is nothing to put in the JSON object. Wrap it in a key if the list is what you wanted: tags: and then the two items, as in the sample.

A file that never opens the fence fails before YAML runs:

No opening --- fence. YAML frontmatter has to be the first line.

title: How DNS works as the whole file is that case. So is a file with a blank line and then ---.

A file that opens and never closes fails with:

No closing --- fence. The first line that is exactly --- ends the frontmatter.

The body cannot be found until that line exists. A horizontal rule later in the article is also three hyphens. If that rule is the first line that is exactly ---, it closes the frontmatter early, and the rest of the article, including the rule, becomes the body. Put the real closing fence before any rule in the article.

Broken YAML uses the parser’s own message. This input is a flow sequence that never closes:

---
title: [
---

The error is:

Flow sequence in block collection must be sufficiently indented and end with a ] at line 2, column 1:

title: [

^

The page does not rewrite that message. The caret points at the [ that was never closed. Fix the YAML, or close the sequence, and the mapping will parse.

An empty document is allowed:

---
---
Body

The JSON is {}, the body is Body plus a newline, and the note is: The YAML document is empty, so the mapping is {}.

A leading BOM, U+FEFF, is removed and noted: A leading BOM was removed before parsing. Some editors on Windows write one. The fence still has to be the first line after that byte.

Line endings can be LF or CRLF. An opening line of --- followed by CR LF is still the fence. The body keeps the line ending it had. A file whose body is the word Line and a CRLF prints that CR in the body. The JSON mapping does not include the carriage return. If a diff of the body shows ^M, the source file used CRLF, and the page copied it through. The key list above the JSON is the same order Object.keys returns after YAML 1.1 parses the mapping. It is the order of the keys in the file, not alphabetical order. title then date then tags then draft in the sample is the order those lines were written.

One more trap. The closer is the first line that is exactly ---, even inside a YAML multiline string. If a folded value contains a line of three hyphens, the frontmatter ends there. Move that line, or indent it so it is not a line of its own.

When the page is the wrong tool

Use this page when you have one Markdown file and you want the mapping and the body separated. A content collection, a Hugo post, or a Jekyll post is the usual file. You can check that draft is a boolean and that the date became the UTC instant you expected.

Use the YAML to JSON converter when the whole file is YAML and there is no body to keep. That page converts a document. It does not look for fences. Use the TOML to JSON converter when the header is TOML, the form some Hugo sites use with +++ fences. This page will not read those fences. Use the JSON formatter when you already have JSON and you only want it pretty-printed.

Astro components also use --- fences, and the text between them is JavaScript, not YAML. Build a documentation site with Astro shows both. The Markdown files in src/content have YAML frontmatter, which is what this page reads. The .astro layout has a script between the same fences, which this page will try to parse as YAML and will reject. Start a blog with Hugo is the other common place you will see the YAML block at the top of a post.

Try the YAML Frontmatter Extractor

Paste a Markdown file and split the YAML frontmatter from the body. Dates become ISO strings. Parsing stays in the browser and is not stored in the URL.

Open the YAML Frontmatter Extractor →

  • YAML ↔ JSON Converter: Convert YAML to JSON and back with indent options, line-number errors, and warnings for classic YAML gotchas.
  • TOML to JSON Converter: Convert TOML to JSON and JSON back to TOML in the browser. Dates become strings, NaN and Infinity become null, and a null value is rejected on the way back.
  • JSON Formatter & Validator: Validate, pretty-print, and minify JSON with clear error messages. Runs entirely in your browser.

More tool tutorials →

Want me to talk about your product? You can sponsor this site.