Skip to content

Frontmatter and dates

Starlight’s built-in fields plus the small set of custom fields this repo adds. Copy the block you need at the top of a new post.


post.md
---
title: RBAC Basics
description: Role-based access control on Kubernetes — Roles, ClusterRoles, and least-privilege ServiceAccounts.
date: 2026-07-30 # custom — sortable; shown only when showDate is true
pubDate: 2026-07-30 # custom — alternative to date, either works
showDate: true # custom — opt in to render date under title + in Recent Posts
draft: false # custom — hides from Recent Posts if true
tags: [kubernetes, security, rbac] # custom — free-form array
sidebar:
order: 1 # sort order within the parent group
label: RBAC # override the sidebar label (default = title)
badge: # inline badge next to the sidebar item
text: Lab
variant: tip # note | tip | danger | caution | success
hidden: false # hide this page from the sidebar entirely
prev: true # true (default) | false | { label, link }
next: false
tableOfContents:
minHeadingLevel: 2
maxHeadingLevel: 3
pagefind: true # false to exclude from search
---

Two custom fields — date and pubDate — behave the same. Pick one and stick with it. Both drive the sort order of Recent Posts, but the date only renders visually when you opt in.

How dates surface (opt-in)

  • Recent Posts (home) sorts by date (fallback pubDate), newest first — always.
  • Rendered date appears next to the title in Recent Posts and under the H1 on the post itself — only when showDate: true.
  • Default is off. Set showDate: true in frontmatter to turn it on for a specific post.

Schema definition (see content.config.ts):

src/content.config.ts
export const collections = {
docs: defineCollection({
loader: docsLoader(),
schema: docsSchema({
extend: z.object({
date: z.coerce.date().optional(),
pubDate: z.coerce.date().optional(),
draft: z.boolean().optional(),
tags: z.array(z.string()).optional(),
showDate: z.boolean().optional(),
}),
}),
}),
};

Autogenerated sidebars sort alphabetically by filename by default. Override with sidebar.order:

post.md
---
title: RBAC Basics
sidebar:
order: 1 # smaller = higher
label: RBAC # shorter than the page title, if you want
---

Two places you can add badges: on the sidebar entry and inline in the body.

post.md
---
title: RBAC Basics
sidebar:
badge:
text: Lab
variant: tip
---

Variants: note, tip, danger, caution, success (+ default).


By default Starlight shows prev/next links based on sidebar order. Frontmatter overrides:

disable-both.md
---
prev: false
next: false
---
custom-link.md
---
title: A follow-up post
prev:
label: Kubernetes overview
link: /kubernetes/
next:
label: Networking
link: /kubernetes/networking/
---

post.md
---
tableOfContents:
minHeadingLevel: 2
maxHeadingLevel: 3 # skip h4 and deeper
---

Or hide it entirely:

tableOfContents: false

Three ways to make a page 'less visible'

  • draft: true → your custom field. Filters out of Recent Posts; page still builds.
  • sidebar.hidden: true → Starlight built-in. Hides from sidebar; page still builds.
  • pagefind: false → excludes from the search index.
  • Really don’t publish? Move it out of src/content/docs/.

For big landing pages, Starlight has a built-in hero renderer:

index.mdx
---
title: Kubernetes
description: Notes on running production-grade Kubernetes.
template: splash # use Starlight's splash template
hero:
tagline: Security, networking, and lab scenarios.
image:
file: ../../../assets/heroes/kubernetes.svg
alt: Kubernetes hero
actions:
- text: Start with Security
link: /kubernetes/security/
icon: right-arrow
variant: primary
---

FieldPurpose
templatedoc (default) or splash (hero + CTAs).
lastUpdatedtrue to show git-based mtime; ISO string to override.
editUrltrue to auto-emit “Edit this page”; false to hide.
headInject extra <head> tags (SEO, canonical, etc.).
banner{ content: 'string' } — page-wide announcement.