Content
Render Markdown from src/content through the koze:content virtual module
Koze discovers Markdown files under src/content/<name>/ and exposes them through the koze:content virtual module. The folder name becomes the property on content.
src/
content/
docs/
getting-started.md
settings/api-keys.md
changelog/
first-release.md
<script>
import { content } from 'koze:content';
const nav = await content.docs.list();
const doc = await content.docs.render('settings/api-keys');
</script>
<aside>
for (const item of nav) {
<a href={item.href}>{item.title}</a>
}
</aside>
if (doc) {
<article>{@html doc.html}</article>
}
Content files
Each Markdown file can include YAML frontmatter:
---
title: API Keys
description: Create and rotate API keys.
section: Settings
order: 20
---
# API Keys
Use short-lived keys for automation.
The content id is derived from the file path below the group:
| File | ID |
|---|---|
src/content/docs/getting-started.md |
getting-started |
src/content/docs/settings/api-keys.md |
settings/api-keys |
src/content/docs/settings/index.md |
settings |
src/content/docs/index.md |
index |
Loose Markdown files directly inside src/content/ are invalid. Put files inside a named group so the runtime API has a stable property to expose.
API
content.<name>.list() returns sorted metadata for every Markdown file in the group:
const docs = await content.docs.list();
Each item includes:
| Field | Description |
|---|---|
id |
Path id used by render(id) |
href |
Default URL-like path, such as /docs/settings/api-keys |
file |
Source file path relative to the project root |
title |
Frontmatter title, first heading, or a titleized filename |
description |
Frontmatter description, when present |
section |
Frontmatter section, when present |
order |
Frontmatter order, defaulting to 999 |
headings |
Extracted Markdown headings with depth, slug, and text |
frontmatter |
Raw frontmatter object |
content.<name>.render(id) returns the same metadata plus the raw Markdown body and rendered HTML:
const doc = await content.docs.render('settings/api-keys');
if (doc) {
console.log(doc.html);
}
Missing ids return null.
Rendering
Markdown rendering uses a CommonMark/GFM pipeline internally. Tables, task lists, fenced code blocks, and heading extraction work out of the box. Raw HTML from Markdown is not passed through by default; render authored team docs as Markdown, and use Koze components/routes for richer interactive UI.
Generated Types
src/app.d.ts is regenerated during dev and build. If src/content/docs exists, content.docs is typed. If src/content/changelog exists, content.changelog is typed. Folder names with dashes are still available with bracket access:
await content['release-notes'].list();