Frontmatter
Alle Frontmatter-Felder, die eine Seite akzeptiert, alle optional — Titel, Beschreibung, Sidebar, SEO, Suche und der Rest, jeweils mit dem, was sie steuern.
Jede Seite akzeptiert die folgenden Frontmatter-Felder. Alle Felder sind optional.
title?string
Page title.
stringdescription?string
Page summary.
stringtype?string
Content type. blog/changelog drive feeds.
stringdocdate?string
Publish date for blog/changelog feeds (ISO or YAML date).
stringauthors?string | string[] | object[]
Post author(s) for blog/changelog content — a name, or objects with a name plus optional avatar/url and any extra fields. Preserved as-is.
string | string[] | object[]slug?string
Override the generated slug.
stringdraft?boolean
Exclude from production builds.
booleanfalsedeprecated?boolean
Mark the page deprecated: its sidebar row gets a deprecated pill (a translatable UI string).
booleanfalsehidden?boolean
Shorthand for sidebar.hidden.
booleanfalsenoindex?boolean
Shorthand for seo.noindex.
booleanfalseicon?string
Lucide icon for the page's sidebar row when sidebar.icon isn't set (sidebar.icon wins).
stringlastModified?string
Pin the page's "last updated" date (ISO or YAML date); overrides the git-derived date.
stringSidebar
sidebar:
label: Install
order: 2
icon: download
badge: New
hidden: false
display: page
hidden entfernt die Seite aus der Sidebar und aus der Zurück/Weiter-Paginierung. Auf der index-Seite eines Ordners entfernt es nur die eigene Zeile der Seite: Die Gruppenzeile verlinkt weiterhin auf die Seite, und die Zurück/Weiter-Links führen weiterhin durch sie hindurch.
display legt den Darstellungsmodus der Ordnergruppe der Seite fest (Überschreibungen pro Gruppe) und ist nur auf der index-Seite eines Ordners in der generierten Sidebar sinnvoll — überall sonst (auf einer Nicht-Index-Seite, der eigenen index-Seite des Content-Stammverzeichnisses oder jeder Seite unter einer expliziten navigation.sidebar) gibt es keine Gruppe zu konfigurieren, und Blume warnt mit BLUME_SIDEBAR_DISPLAY_IGNORED.
SEO
seo:
title: Install Blume
description: Install Blume and scaffold your first project.
image: /og/install.png
canonical: https://acme.com/install
noindex: false
x:
creator: "@jane"
noindex gibt ein robots-noindex aus, entfernt die Seite aus der Sitemap und lässt ihre strukturierten Daten weg. x.creator schreibt die Seite einem X-Account zu (twitter:creator) — etwa der Person, die einen Gastbeitrag verfasst hat. Alle Felder findest du unter Metadaten.
Suche
search:
exclude: false
tags: [api]
KI
ai:
exclude: true
ai.exclude hält die Seite aus llms.txt und llms-full.txt heraus. Die Seite wird trotzdem gerendert, bleibt in der Suche und behält ihren Platz in der Sitemap.
Changelog
Changelog-Einträge (type: changelog) akzeptieren ein optionales changelog-Objekt für umfangreichere Feed- und Anzeige-Metadaten:
type: changelog
changelog:
version: 1.2.0
date: 2026-06-20
category: Features
date kann hier oder auf oberster Ebene stehen — beides fließt in den Changelog-RSS-Feed ein. Die generierte Timeline-Seite und den Feed findest du unter Changelog.
Eigene Schlüssel
Jeder Schlüssel, der nicht in dieser Referenz steht, lässt den Build fehlschlagen, sodass Tippfehler früh auffallen. Projekte mit eigenen Metadaten können zusätzliche Schlüssel über frontmatter.extend in blume.config.ts freischalten. Jeder davon wird durch ein Schema validiert, das das Projekt selbst mitbringt:
import { defineConfig } from "blume";
import { z } from "zod";
export default defineConfig({
frontmatter: {
extend: {
owner: z.string(),
reviewedAt: z.coerce.date().optional(),
},
},
});
---
title: Install
owner: "@sam"
reviewedAt: 2026-06-20
---
Schemas werden über die Standard Schema-Schnittstelle akzeptiert, sodass Zod (egal welche Version dein Projekt installiert hat), Valibot und ArkType alle funktionieren. Jeder deklarierte Schlüssel wird auf jeder Seite validiert, auch dort, wo er fehlt. Ein Pflichtschema erzwingt den Schlüssel also auf der gesamten Website. Markiere ihn mit .optional(), damit er nur dort validiert wird, wo er vorhanden ist. Alle anderen Schlüssel werden weiterhin strikt validiert, und eingebaute Felder kannst du nicht neu deklarieren.
Schlüssel pro Typ
Wenn du Schlüssel nur für einen bestimmten Inhaltstyp verlangen willst, etwa den status eines RFC oder die severity eines Incident-Reports, deklariere sie stattdessen unter content.types. Als Schlüssel dient dabei der Frontmatter-type, für den sie gelten:
import { defineConfig } from "blume";
import { z } from "zod";
export default defineConfig({
content: {
types: {
rfc: {
frontmatter: {
domain: z.string(),
status: z.enum(["draft", "review", "enforced"]),
},
},
},
},
});
---
title: OpenAPI request schemas
type: rfc
domain: architecture
status: enforced
---
Schlüssel pro Typ folgen denselben Validierungsregeln wie extend, gelten aber nur für Seiten, deren aufgelöster type passt. Ist die Deklaration für content.defaultType, gehören dazu auch Seiten, die gar keinen type setzen. Ein Schlüssel gehört zu genau einer Deklaration, entweder für die gesamte Website oder pro Typ, nicht zu beiden. Ein Schlüssel, der nur für einen anderen Typ deklariert ist, bleibt überall sonst unbekannt. Ein verirrter status auf einer normalen Doku-Seite lässt den Build also weiterhin fehlschlagen.
Besteht eine Seite die Validierung nicht, schlägt blume build fehl, und die Diagnose nennt Datei und Schlüssel. Mit --no-strict läuft der Build trotzdem durch, und die fehlerhaften Seiten werden aus der Ausgabe entfernt. Wie viele das sind, steht in der Build-Zusammenfassung.
Die Schemas werden aus blume/schema exportiert, damit du sie für Editor- und Migrations-Tools nutzen kannst.