Skip to content

Docs Frontmatter

Shoehorn parses an optional YAML frontmatter block at the top of every Markdown document it ingests. Frontmatter lets you tag a doc with a category, override the title and description shown in the Docs Hub, and link the doc to specific catalog entities.

If a doc has no frontmatter, it is still indexed and searchable. It just won’t appear in the Docs Hub category filters.

A frontmatter block is fenced by --- lines and must be the very first thing in the file:

---
category: runbook
title: "Payment Service: Failed Charge Recovery"
description: "How to recover stuck charges when Stripe webhooks fail."
related_entities:
- payments-api
- billing-worker
---
When a webhook delivery from Stripe fails...

Rules:

  • The opening --- must be on the first line of the file.
  • The closing --- must be on its own line.
  • Body content begins on the line after the closing fence.
  • All fields are optional. A missing or empty field is simply ignored.
  • A malformed YAML block is logged and treated as “no frontmatter”. Your doc still gets indexed, it just won’t have frontmatter-driven metadata.
FieldTypePurpose
categorystringGroups the doc under a chip in the Docs Hub category strip.
titlestringOverrides the auto-detected title (otherwise the first # H1 is used).
descriptionstringCard subtitle in the Docs Hub and search snippets.
related_entitiesstring listLinks the doc to one or more catalog entities.

The category becomes a filterable chip in the Docs Hub. Categories are dynamic: any value you write becomes a chip, you don’t need to pre-register it.

Categories are normalized before indexing:

  • Trimmed and lowercased (so Runbook, runbook, and RUNBOOK all collapse to runbook).
  • Allowed characters: ASCII letters, digits, and . _ / -.
  • Maximum length: 64 characters.
  • Values starting with _ are reserved (used internally for the “Other” overflow chip) and will be dropped.

If a category fails normalization (e.g. contains spaces, emoji, or non-ASCII characters), the doc is indexed without a category and won’t appear in any category filter.

These slugs ship with built-in translated labels and reserved colors. You can still use any other slug you like. It just won’t get a curated label.

SlugLabel
onboardingOnboarding
runbookRunbooks
architectureArchitecture
apiAPI
securitySecurity

Sets the document title in the Docs Hub card, search results, and entity Documentation tab. If omitted, Shoehorn falls back to the first # H1 in the body.

A short blurb shown as the card subtitle in the Docs Hub and as the snippet in search results. Aim for one sentence (under ~160 characters).

If omitted, Shoehorn auto-generates a summary from the first paragraph of the body.

A list of catalog entity names that the doc relates to. Use the entity’s slug (the same name shown in the catalog), one per line. Inline list form ([payments-api, billing-worker]) also works.

Related entities are surfaced:

  • On the doc card in the Docs Hub (as small entity chips)
  • In the entity’s Documentation tab (so the doc appears even if it lives in another repository)

Frontmatter is extracted from Markdown sources Shoehorn ingests:

  • READMEs discovered in repositories
  • Runbook files referenced from manifests or annotations
  • Changelogs
  • Doc-site Markdown crawled by the docs crawler

After extraction, the frontmatter block is stripped from the body before rendering, so it never appears as raw text in the rendered doc.

---
category: onboarding
title: "New-Hire Setup: Local Dev Environment"
description: "Get a local checkout building and tests passing in under 30 minutes."
---
---
category: runbook
title: "Recover from Redis Eviction Storm"
description: "Steps for the on-call to clear runaway Redis evictions."
related_entities:
- cart-api
- session-store
- checkout
---
---
category: post-mortem
title: "2026-03-14 Checkout Outage"
description: "Root-cause analysis for the 47-minute checkout outage on Pi Day."
---

The post-mortem chip will appear in the Docs Hub alongside the built-in chips.

SymptomLikely cause
Doc isn’t filtered under your category chipCategory contains disallowed characters (spaces, emoji, non-ASCII), normalize to ASCII slug.
Frontmatter rendered as text in the doc bodyOpening --- isn’t on the very first line, or the closing fence is missing.
Doc has no description / wrong title in the HubYAML parse error, Shoehorn logged a warning and fell back to body-only. Validate the YAML block.
Related entities don’t show upEntity reference doesn’t match a catalog entity, or the kind/name pair is wrong.

The category slug is used in downstream search filters, so the parser enforces a strict ASCII allowlist as defense-in-depth against filter injection. This is why category values are limited to letters, digits, and . _ / -, it is intentional and won’t be loosened.