Frontmatter reference: every field this theme understands
A complete reference for the post and page frontmatter schema Erequired and optional fields, defaults, validation rules, and what each one actually does.
This theme uses Astro Content Collections with a strict
Zod schema. Every post and page is type-checked at
build time, so a missing required field or a typo in pubDate fails
loudly instead of silently breaking the site.
The full schema lives in src/content.config.ts. Here is what each field does, when you need it, and what it defaults to.
| Field | Type | Notes |
|---|---|---|
title | string | 1 E40 characters. Used as <title>, OG title, H1. |
description | string | 1 E80 characters. Used as meta description, OG, RSS. |
pubDate | date | Coerced from any ISO-parseable string. |
For pages (src/content/pages/**), pubDate is optional Epages
are not paginated or archived.
updatedDate: 2026-05-12Set this whenever you make a meaningful edit. It controls the “Updated”
line in the post header, the RSS <updated> tag, the OG
article:modified_time meta and the sitemap entry.
tags: [typescript, astro, accessibility]categories: [Tutorials]Both default to []. Tags drive the /tags/... index. Categories drive
/categories/.... Both appear on the right-hand panel when ranked
high enough in the “Trending tags” widget. There is no enforced
case-style Epick a convention and stick to it.
draft: trueDefault false. When true, the post is included in dev mode (so you
can see it while writing) but excluded from production builds, the
sitemap and the RSS feed.
heroImage: ../../assets/images/posts/featured-images-and-media/coastline.jpgheroImageAlt: 'A long exposure of waves crashing on a rocky coastline'Three shapes are accepted:
- A path relative to the markdown file pointing into
src/assets/images/posts/<post-identifier>/Eresolved through Astro’simage()helper, fully optimized (WebP + responsivesrcset). Recommended. - A
/public/...absolute path Eserved as-is, no optimization. - An external
https://...URL Eoptimized at build if the host is allow-listed inimage.remotePatterns(seeastro.config.mjs).
The image is used both as the card thumbnail on listings and as the
hero on the post page. heroImageAlt becomes the alt attribute Eplease always set it.
The companion post Featured images & media goes deeper into image authoring.
showFeaturedImage: falseA per-post override of SITE.showFeaturedImages from
src/config.ts. Set false to suppress the hero on a
single post even though the site default is “show”.
For listing-card sizing behavior (fixed vs dynamic height), use
SITE.dynamicPostCardHeight in src/config.ts for the
site default, or set dynamicPostCardHeight in frontmatter to override
it per post.
dynamicPostCardHeight: trueOptional per-post override of SITE.dynamicPostCardHeight. This only
affects how the post’s card behaves on horizontal listing views:
true: this post’s listing card can grow (dynamic height).false: this post’s listing card keeps fixed Chirpy-style height.- omitted: falls back to the site-level
SITE.dynamicPostCardHeight.
canonicalURL: https://example.com/canonical/path/Optional override for the <link rel="canonical"> tag. Useful when
republishing a post that already lives elsewhere.
comments: falsePer-post toggle for Giscus. If omitted, comments follow the site-wide
GISCUS.enabled setting. Set explicitly to false to silence comments
on a single post (e.g. on this very reference page).
toc: falseDefaults to true. The right-hand sticky table of contents is built
from your H2–H4 headings with scroll-spy. Some posts (a photo essay,
a short announcement) read better without one Eset toc: false.
pinned: truePinned posts always sort to the top of listings and the home page, above newer posts. Use sparingly.
math: trueOpt the post into KaTeX rendering. The stylesheet (katex.min.css,
~29 kB) is only loaded on pages that set this flag. See the
LaTeX math post for full syntax.
lang: enLocale override. The theme normally infers locale from the file
path (posts/en/... ↁEen, posts/fr/... ↁEfr), so you should
rarely need this.
translationKey: welcomeThe bridge between EN and FR variants of the same article. Two posts
that share a translationKey are considered translations of each
other; the language switcher uses this to land you on the equivalent
article instead of bouncing to the locale home page. If omitted, the
theme falls back to the file slug. The
i18n post shows the full picture.
Pages (src/content/pages/**) accept everything posts do (with
pubDate made optional) plus:
showInNav: trueThis is reserved for future use; navigation is currently driven by the
NAV array in src/config.ts.
---title: A complete exampledescription: Demonstrates every field in one place.pubDate: 2026-05-01updatedDate: 2026-05-03tags: [example, reference]categories: [Reference]draft: falseheroImage: ../../assets/images/posts/featured-images-and-media/coastline.jpgheroImageAlt: A long exposure of a rocky coastlineshowFeaturedImage: truecanonicalURL: https://example.com/example/comments: truetoc: truepinned: falsemath: falsetranslationKey: example---| Error | What it means |
|---|---|
pubDate: Required | You forgot pubDate (or misspelled it). |
description: Too long (max 280) | Your description exceeds 280 characters. |
heroImage: Invalid URL | (Only fires for external URLs that fail Zod’s URL parse.) |
Cannot find module '...' | An MDX import path is wrong Echeck the relative path to src/components/. |
Comments are intentionally turned off for this post via
comments: false Eit is a reference, not a discussion.