MDX Directives
Overview of all built-in directives available in content files.
These directives are available in every .mdx file — no import needed. Each has
its own page with a full reference and live examples.
| Directive | Description |
|---|---|
::article-list | Sorted article list from a content directory |
::article-list-item | Single article row (used internally by ::article-list) |
::table-of-contents | Scroll-aware heading navigation |
::spacer | Vertical whitespace |
::progress-bar | Progress bar with a fixed value or live date-range math |
:::timeline | Vertical job-experience timeline container |
:::timeline-item | Individual role entry inside a :::timeline |
:::callout | GitHub-style note, tip, warning, or caution box |
- directives/article-listarticle-list
Renders a sorted list of articles from a content directory.
Read - directives/calloutcallout
Renders a GitHub-style callout box with a colored border, tinted background, and an icon — for notes, tips, warnings, and more.
Read - directives/progress-barprogress-bar
Renders a labeled progress bar, either with a fixed value or calculated live from a date range.
Read - directives/spacerspacer
Inserts vertical whitespace between elements.
Read - directives/table-of-contentstable-of-contents
Auto-detects headings and renders a linked, scroll-aware navigation list.
Read - directives/timelinetimeline
Renders a vertical timeline from structured entries with freeform badge metadata.
Read
Directive syntax
Block-level (leaf) directives use a double-colon prefix:
::directive-name
::directive-name{attr=value flag}Attributes follow a simple coercion scheme — no quotes or braces needed for common cases:
| Written as | Prop received | Example |
|---|---|---|
attr=text | string | dir=guides → dir="guides" |
flag (no value) | true (boolean) | recursive → recursive={true} |
attr=false | false (boolean) | recursive=false → recursive={false} |
attr=5 | number | limit=5 → limit={5} |
How directives map to components
Each directive name is converted from kebab-case to PascalCase, then looked up
in the MDX component map. No additional configuration is needed — a new
component registered in mdxComponents is immediately usable as a directive:
| Directive | Component |
|---|---|
::spacer | <Spacer /> |
::article-list | <ArticleList /> |
::table-of-contents | <TableOfContents /> |
::progress-bar | <ProgressBar /> |
:::timeline | <Timeline /> |
:::timeline-item | <TimelineItem /> |
:::callout | <Callout /> |
Adding new directives
- Create the underlying component in
src/components/mdx/. - Export it from
src/components/mdx/index.tsxand add it to themdxComponentsmap.
The directive name is derived automatically: kebab-case the component name (e.g.
MyWidget → ::my-widget).
Special directives
::nav-section is not part of mdxComponents. It is parsed at build time by
src/lib/nav.ts exclusively from content/_nav.mdx to populate the sidebar. It
cannot be used in regular content files. See the
Sidebar reference for the full attribute reference.