Writing Content
(Last Edited)
Content directory
All content lives in content/ at the project root. The URL path mirrors the
filesystem path exactly:
| File | URL |
|---|---|
content/index.mdx | / |
content/about.mdx | /about |
content/blog/post.mdx | /blog/post |
content/blog/ (directory) | /blog (article listing) |
Frontmatter
Every MDX file should start with a YAML frontmatter block:
---
title: My Page # required
description: A short blurb. # required
date: 2026-01-15 # optional — shown in header and listing cards
lastEdited: 2026-02-01 # optional — shown in header if different from date
author: your name # optional
tags: [one, two] # optional
draft: true # optional — hides the file from directory listings
---lastEdited falls back to the file's filesystem mtime when omitted. It is only
displayed in the article header if it differs from date.
Directory listings
A directory without an index.mdx automatically renders a listing of all
non-draft MDX files inside it, sorted by date descending (undated files sort
last). No configuration needed.
To embed a listing inside any MDX file, use the <ArticleList> component:
<ArticleList dir="blog" />
<ArticleList dir="blog" limit={5} />Drafts
Set draft: true in frontmatter to exclude a file from directory listings and
<ArticleList>. The page is still accessible directly by URL during
development.
MDX
Any valid Markdown is also valid MDX. You can embed JSX components anywhere in the body. The built-in components are documented in MDX Components.
Math
Inline math with $...$ and block math with $$...$$:
Euler's identity: $e^{i\pi} + 1 = 0$
$$
\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi}
$$Code blocks
Fenced code blocks are highlighted by Shiki. Specify the language after the opening fence:
```ts
const greeting: string = 'hello';
```