Frontmatter #

Frontmatter is optional metadata placed at the very top of a Djot page, before any content. Glaze reads it as NEON – the same format used by glaze.neon.

Fence syntax #

You can use either +++ or --- as opening and closing fences:

---
title: Hello world
slug: /
draft: false
template: page
tags:
  - intro
  - welcome
meta:
  robots: index,follow
---
# Hello world

Welcome to Glaze.

Both fence styles are equivalent. Frontmatter is entirely optional – pages without it will have their title inferred from the filename.

Field reference #

Reserved keys are interpreted by Glaze runtime features:

  • title
  • slug
  • date
  • weight
  • draft
  • type
  • template
  • description
  • meta (page metadata override map used for generated <meta> defaults)
  • taxonomy keys configured in glaze.neon (tags, categories, …)

Common convention keys (used by templates/themes, not reserved by core):

  • section (override folder-derived section slug)
  • navigation (include/exclude page from navigation)
  • navigationTitle (alternate title for menus)

All other keys are treated as custom frontmatter data and are preserved as-is, including nested maps and lists.

title #

Human-readable page title. When omitted, Glaze infers a title from the slug (e.g. my-post becomes My Post).

---
title: Getting started with Glaze
---

slug #

Overrides the URL path derived from the file path. Useful for custom routes like / for the home page.

---
slug: /
---

Slug values are normalized (lowercased and slugified).

date #

Publish date or datetime. Must be a value parseable as a date or datetime.

---
date: 2026-02-24
---
---
date: 2026-02-24T14:30:00+01:00
---

Glaze normalizes date to a Cake\Chronos\Chronos instance. If the value cannot be parsed, content discovery throws an exception.

In templates:

<?php $date = $page->meta['date'] ?? null; ?>

<?php if ($date instanceof \Cake\Chronos\Chronos): ?>
    <time datetime="<?= $date->toIso8601String() ?>">
        <?= $date->format('F j, Y') ?>
    </time>
<?php endif; ?>

weight #

Integer sort order for page collections. Lower values sort first. Useful for controlling navigation menus, ordered documentation sections, or any list where file-path ordering is not sufficient.

---
weight: 10
---

In templates, sort a collection by weight:

<li s:foreach="$this->pages()->by('meta.weight', 'asc') as $p">
    <a href="<?= $p->urlPath ?>"><?= $p->title ?></a>
</li>

Navigation-focused usage of weight, section, navigation, and navigationTitle is covered in Templating and Page Collections.

draft #

Marks the page as a draft. Draft pages are excluded from glaze build output unless --drafts is passed. The live server (glaze serve) includes drafts by default.

---
draft: true
---

type #

Explicitly assigns a content type when contentTypes are configured in glaze.neon. Normally the type is resolved automatically from the file path. Use this to override:

---
type: blog
---

template #

Overrides the default page template for this page. The value is a template name (without .sugar.php extension) relative to templates/.

---
template: landing
---

This causes the page to render with templates/landing.sugar.php instead of the configured default.

Taxonomy fields #

Any key listed under taxonomies in glaze.neon is extracted as a taxonomy. Values can be a single string or a NEON list.

---
tags:
  - php
  - static-sites
categories:
  - tutorials
---

Custom fields #

Use any non-reserved key for custom page data. Nested maps/lists are preserved and can be read with dotted access in templates.

---
hero:
  title: Build fast static sites
  primaryAction:
    label: Read docs
    href: /installation
---

In templates:

<?= $page->meta('hero.title') ?>
<?= $page->meta('hero.primaryAction.href') ?>

meta can still be used as a key if you want, but it is no longer required as a wrapper for nested data.

How Glaze processes frontmatter #

  • All keys are normalized to lowercase
  • date is converted to Chronos; an unparseable value is an error
  • Taxonomy keys are extracted into $page->taxonomies; the rest lands in $page->meta
  • Unknown keys are kept in $page->meta without validation
  • Content type defaults from glaze.neon are merged in, with page frontmatter taking precedence
  • type resolves via path matching first, then explicit frontmatter override

Next: Configuration and Templating.