Guide

Writing content

Front matter, sections, bundles, summaries and drafts.

3 min read

Files and URLs #

A file’s path under content/ becomes its URL:

FileURL
content/_index.md/
content/about.md/about/
content/blog/_index.md/blog/ (a section listing)
content/blog/hello.md/blog/hello/
content/blog/hello/index.md/blog/hello/ (a bundle)

URLs always end in a slash and are written as dir/index.html, so they work on any static host.

Front matter #

YAML between --- lines at the top of a file:

---
title: My post
date: 2026-10-10
draft: false
tags: [rust, web]
slug: custom-url-segment
description: Shown in listings, feeds and <meta>.
weight: 10
template: page.html
---
KeyMeaning
titlePage title. Defaults to a humanised file name.
dateYYYY-MM-DD (RFC 3339 and YYYY-MM-DD HH:MM:SS also accepted). Only the calendar date is used.
expiry_dateThe page is hidden from this date on.
draftExcluded unless built with --drafts.
slugReplaces the last URL segment. May not contain /, \, : or ...
templateUse a specific template instead of the default.
weightSort key when a section uses sort_by: weight; also a tiebreaker.
tags and any other listTaxonomy terms, if the taxonomy is enabled in config.yml.
anything elseAvailable to templates as page.meta.<key>.

Section pages (_index.md) also accept sort_by (date newest first, weight, or title) and paginate_by.

Bundles #

Put a page and its assets together:

content/blog/trip/index.md
content/blog/trip/map.png

map.png is published next to the page, so ![map](map.png) just works.

Summaries, reading time and the table of contents #

  • Everything before <!-- more --> is the page’s summary; without it, the first paragraph.
  • page.word_count and page.reading_time (minutes, 200 wpm) are computed for you.
  • page.toc lists headings with level, id and title. Every heading also gets an anchor link.

Dates and visibility #

  • Pages dated in the future are skipped unless you build with --future (or build.future: true).
  • Pages past their expiry_date are always skipped.
  • “Today” is the current date in UTC.

Code highlighting #

Fenced blocks with a known language are highlighted at build time, so no JavaScript is needed. Meteorite writes CSS classes into the HTML and generates a highlight.css with two palettes: one for light mode and one for dark mode, so code follows the visitor’s colour mode.

markdown:
  highlight: true
  highlight_theme: InspiredGitHub        # light mode
  highlight_theme_dark: base16-ocean.dark   # dark mode
  highlight_style: classes               # or: inline

Bundled colour schemes include InspiredGitHub, base16-ocean.dark, base16-ocean.light, base16-eighties.dark, base16-mocha.dark, Solarized (dark) and Solarized (light). An unknown name is a build error that lists the available ones.

  • classes (default): themes must link highlight.css (the bundled themes do).
  • inline: colours are written as style attributes using only highlight_theme. No stylesheet is needed, but there is no dark palette.
  • highlight: false turns highlighting off.

Shortcodes #

Shortcodes are reusable snippets rendered from templates/shortcodes/<name>.html.

{{< youtube id="dQw4w9WgXcQ" />}}

{{< note kind="warn" >}}
Paired shortcodes pass their Markdown body to the template as `body`.
{{< /note >}}

Arguments are key="string", key=42, key=1.5 or key=true and become template variables. Shortcodes are never expanded inside fenced code blocks or inline code, so you can document their syntax. An unknown name or an unclosed pair is a build error that names the file.