RMarkdown Header: YAML Options and Headings (2026)

September 11, 2026 · 11 min read

RMarkdown Header: YAML Options and Section Headings Explained

An RMarkdown header means one of two things. Section headings use # marks, exactly like plain Markdown. The YAML header sits between two --- fences at the top of the file and controls the title, author, date, and output format. This guide covers headings briefly, then walks through every common YAML field, per output format, with the errors that trip people up.

How Do You Do Headers in R Markdown?

Section headers in an .Rmd file are ordinary Markdown headings. One # gives you a level 1 heading, ## a level 2, down to ###### for level 6. R Markdown hands the file to Pandoc, so Pandoc's heading rules apply. You need a space after the # marks, and a blank line before the heading unless it's the first line of the body.

# Results

## Sales by region

### Europe

That renders as an H1, an H2, and an H3 in HTML, as section, subsection, and subsubsection in a PDF, and as Heading 1, 2, and 3 styles in Word. Pandoc's blank_before_header extension is the reason a heading pasted directly under a paragraph shows up as plain text. Add the blank line and it renders.

Two Pandoc extras are worth knowing. You can attach an ID or class in curly braces at the end of the line, such as ## Next Steps {#nextsteps}, and link to it with [see next steps](#nextsteps). And in HTML output, ## Quarterly Results {.tabset} turns every H3 below it into a clickable tab. The general rules for levels, anchors, and spacing live in our Markdown headings guide; the rest of this post is about the other header.

What Is the YAML Header in R Markdown?

The YAML header (RStudio also calls it the YAML metadata or front matter) is a block of key: value lines fenced by --- on its own line above and below. It must be the very first thing in the file. R Markdown reads it to decide what to render and how; the text itself never appears in the output except through fields like title.

---
title: "Habits"
author: "John Doe"
date: "2026-09-11"
output: html_document
---

That minimal block is what RStudio generates for a new document. The four fields are the ones almost every file uses:

  • title, author, and date fill the title block at the top of the rendered document. Quote them if they contain a colon, a #, or start with a special character.
  • output names the format. As a single value it takes the defaults. Written as a nested key, it accepts options for that format.

Everything in this guide builds on those two shapes of output.

How Do I Write a YAML Header in R Markdown?

YAML is picky about whitespace, and most "Error in yaml::yaml.load" messages come from three habits. Indent nested options with two spaces (tabs aren't YAML). When you add options to an output format, the format name becomes a key and needs a trailing colon. And put a space after every colon that separates a key from a value.

---
title: "Report: Q3 2026"
output:
  html_document:
    toc: true
    toc_depth: 2
---

Compare that to the broken version people write first: output: html_document on one line followed by an indented toc: true. YAML reads html_document as a plain string, sees children under it, and stops. The fix is the colon after html_document: and moving the format onto its own indented line.

The title is quoted because it contains a colon. Without quotes, YAML would treat Report as a key and the rest as its value, then fail on the duplicate structure. Quoting also protects titles that begin with *, &, !, or [.

One more trick worth its own line: you can run inline R inside the header. The value has to be a quoted string so the backticks survive YAML parsing, as the R Markdown Cookbook shows:

date: "`r format(Sys.time(), '%d %B, %Y')`"

R evaluates the expression each time you knit, so the date always matches the render date. Note the single quotes inside the double quotes; nesting them the other way round breaks the string.

R Markdown YAML Header Options by Output Format

Here is the same document header written for HTML, PDF, and Word so you can see what changes. The top-level fields stay identical; only the output block moves.

---
title: "Quarterly Sales"
subtitle: "Europe, Q3 2026"
author: "Data Team"
date: "`r Sys.Date()`"
output:
  html_document:
    toc: true
    toc_float: true
    number_sections: true
    theme: flatly
    highlight: tango
    code_folding: hide
    df_print: paged
---

For a PDF, swap the block for pdf_document. Some options keep their names, one changes its default, and a few are LaTeX-only:

output:
  pdf_document:
    toc: true
    toc_depth: 2
    number_sections: true
    latex_engine: xelatex
    keep_tex: true
    includes:
      in_header: preamble.tex
fontsize: 11pt
geometry: margin=1in
---

The Word version is the shortest, because styling comes from a reference document rather than YAML fields:

output:
  word_document:
    toc: true
    reference_docx: my-styles.docx
---

Notice that fontsize and geometry sit at the top level, not under pdf_document. They're Pandoc template variables, and R Markdown passes them straight through to the LaTeX template. Putting them under the output format is a common mistake that silently does nothing.

Every common field and where it applies

FieldWhat it doesHTMLPDFWord
title, subtitle, author, dateTitle block at the top of the documentYesYesYes
toc: trueAdds a table of contents from your headingsYesYesYes
toc_depthDeepest heading level in the TOC (default 3 for HTML, 2 for PDF)YesYesYes
toc_float: trueKeeps the TOC visible in a sidebar while scrollingYesNoNo
number_sections: trueNumbers headings 1, 1.1, 1.2YesYesYes
themeBootswatch page theme; null removes stylingYesNoNo
highlightCode colour scheme (tango, pygments, kate, zenburn, others)YesYesYes
code_folding: hide or showCollapsible R code chunksYesNoNo
df_printHow data frames print: default, kable, tibble, pagedYesYes (no paged)Yes
cssExtra stylesheet fileYesNoNo
latex_enginepdflatex (default), xelatex, or lualatexNoYesNo
keep_tex: trueKeep the intermediate .tex fileNoYesNo
includes: in_headerLaTeX or HTML to inject into the preamble or headYesYesNo
reference_docxWord template for styles and marginsNoNoYes
paramsNamed inputs your code can read as params$nameYesYesYes
bibliography, cslReference file and citation styleYesYesYes

Valid theme names for html_document are default, bootstrap, cerulean, cosmo, darkly, flatly, journal, lumen, paper, readable, sandstone, simplex, spacelab, united, and yeti. Misspell one and the render stops with an error rather than falling back to the default. We prefer flatly for reports and null plus a custom css file when the document has to match a house style. The full option lists are in the R Markdown: The Definitive Guide chapters on HTML and PDF documents.

toc: true is the R Markdown equivalent of the manual and generated approaches in our Markdown table of contents post, except it rebuilds itself on every knit.

Try the RMarkdown Header Syntax in the Editor

The Markdown half of an R Markdown file renders anywhere. Edit the headings below and watch the levels change. A limitation to know about: a plain Markdown renderer treats the --- fences as horizontal rules and the YAML fields as text. The closing fence even turns the last field into a heading. So leave the front matter out when you preview here and let R Markdown handle it at knit time.

Quarterly Sales

Written in R Markdown. The YAML header sits above this line at knit time.

Sales by region

Headings need a space after the hash marks and a blank line above.

Europe

Regional detail goes here.

Asia

Link back to a section with an anchor: see Europe.

Methods

Numbered by number_sections: true, listed by toc: true.

62 words362 characters19 lines
Markdown

Params, Bibliography, and Custom Page Headers

Three fields go beyond formatting. Each lives at the top level of the YAML header.

params declares named values your chunks read with params$year or params$region. Set defaults in the header, then override them from the console without editing the file:

params:
  year: 2026
  region: Europe
rmarkdown::render("report.Rmd", params = list(region = "Asia"))

Any parameter you don't pass keeps its YAML default. The !r tag lets a default run R code, for example date: !r Sys.Date(). The parameterized reports chapter covers the Knit with Parameters dialog too.

bibliography points at a .bib file, and csl picks a citation style. Cite with [@key] in the text and Pandoc writes the reference list at the end.

Custom page headers and footers are the "rmarkdown header logo pdf" problem. R Markdown has no YAML field for a running header; it's a LaTeX job using the fancyhdr package. Save this in preamble.tex:

\usepackage{fancyhdr}
\pagestyle{fancy}
\fancyhead[L]{\includegraphics[height=1cm]{logo.png}}
\fancyhead[R]{Quarterly Sales}
\fancyfoot[C]{\thepage}

Then reference it with includes: in_header: preamble.tex under pdf_document, as in the PDF example above. The alternative is a header-includes: field at the top level holding the same LaTeX lines. That keeps everything in one file, but it's applied to every output format, so HTML renders will complain. For a document that only ever becomes a PDF, either works. Logos in the HTML title area need a small CSS rule or an includes: before_body fragment instead.

Common RMarkdown Header Mistakes

Tabs instead of spaces. RStudio inserts spaces when you press Tab in an .Rmd file, but text pasted from elsewhere can carry real tab characters. YAML rejects them with a "found character that cannot start any token" error. Retype the indentation with two spaces per level.

Options under the wrong parent. toc: true placed at the top level, beside title, is ignored. It belongs under the output format. The reverse error is fontsize: 12pt nested under pdf_document, which is also ignored; that one goes at the top level. If a field does nothing, check which parent the documentation puts it under.

An unquoted title with a colon. title: Report: Q3 fails with a "mapping values are not allowed in this context" message. Wrap the value in double quotes. The same applies to a date or author that contains a colon, and to any value starting with @, #, *, or [.

RMarkdown Header FAQ

Once the two meanings are clear, an RMarkdown header stops being mysterious: headings follow Pandoc's Markdown rules, and the YAML block is a small, strict configuration file where indentation and colons carry meaning. Keep the field table above beside you when you switch output formats, quote anything with punctuation, and preview the Markdown half of your document in the editor before you knit. For chunk options and inline code, see the R Markdown cheat sheet.