All content lives in src/content/. Each folder is a collection with a schema in src/content.config.ts; a typo in frontmatter fails the build with a clear message instead of silently rendering wrong. Files whose name starts with _ are ignored everywhere.
Posts
Create src/content/posts/my-post.md (or .mdx). Sub-folders are allowed — the file path becomes the URL, so posts/gpus-on-kubernetes/part-1.md is served at /posts/gpus-on-kubernetes/part-1.
---title: 'My post'description: 'One or two sentences for the list, RSS, and social cards.'date: 2026-07-20updated: 2026-07-25 # optionaltags: ['kubernetes', 'gpu']series: 'GPUs on Kubernetes' # optional — enables "in this series"image: '/images/posts/cover.png' # optional — cover + Open Graph imageexternalLink: 'https://…' # optional — link the title elsewheredraft: false---
Your content here.seriesgroups posts: every post with the same series name gets a numbered “in this series” block, in reading order.externalLinkturns the post into a link-out (no page is generated) — handy for talks and guest posts.- Drafts render in
npm run devbut are skipped bynpm run build.
Images with captions
An image on its own line with alt text becomes a <figure> with a caption:
Every Markdown image is lazy-loaded. External links open in a new tab with rel="noopener noreferrer".
Code blocks
Fenced blocks are rendered by Expressive Code. Useful meta on the opening fence:
| Fence meta | Effect |
|---|---|
yaml title="deployment.yaml" {3-4} |
editor frame with a file name, lines 3–4 highlighted |
bash frame="terminal" |
terminal frame |
go showLineNumbers |
line numbers |
yaml ins={4} del={3} |
green / red diff markers |
Code blocks stay dark in every scene, light ones included — see Scenes & colours to change that.
Projects
---title: 'Rollout Sentinel'description: 'What it is, in one sentence.'image: '/images/projects/rollout-sentinel.svg' # or .png / .webp / .webm / .mp4skills: ['Go', 'Kubernetes', 'Prometheus']link: 'https://github.com/…' # where the title goessourceCode: 'https://github.com/…' # optional separate repo linkorder: 1featured: true---A project with no body is a row/card that links out. A project with body content also gets its own page at /projects/<id>, and the title links there instead (the outbound link becomes a “view project” link on the card). link may be an internal path such as /tags/gpu if the “project” is a series of posts. Videos (.webm, .mp4) autoplay muted and looped.
Docs
---title: 'My guide'description: 'Shown in the docs index and as the page subtitle.'group: 'Guides' # sidebar headingorder: 10 # position within the group---Groups appear in the order their first page is encountered (by order), so give your “Getting Started” pages the lowest numbers.
Pages
Any file in src/content/pages/ becomes a top-level route: about.md → /about, uses.md → /uses. The page shows a ~/about kicker, the title, and the description as a lede.
---title: 'About'description: 'Optional lede under the title.'noindex: false---MDX components
In .mdx files the <Callout> and <Tabs> components are available without imports — see Component reference. The post Writing with MDX shows every feature on one page.