Authoring
JSON schema
Presentation content is a strict JSON document. Unknown keys are errors, and every layout has its own required fields.
Presentation
The executable schema is src/schemas/presentation.ts, written with Zod. parsePresentation validates input and applies defaults.
| Field | Required | Value |
|---|---|---|
| metadata | Yes | title (required), author, subject, lang (default en) |
| theme | No | light (default) or dark |
| fontFamily | No | Local font family list, up to 200 characters |
| slides | Yes | 1 to 200 slides |
Slides and layouts
Every slide needs layout and title, and may have subtitle, footer, and notes. Notes become PowerPoint speaker notes. Each layout adds its own fields:
| layout | Fields |
|---|---|
| cover | Optional author |
| content | blocks: 1–12 content blocks |
| two-columns | left and right: 1–12 blocks each |
| cards | cards: 1–6 cards with title and blocks |
| table | columns (1–8) and rows (1–14), one cell per column |
| chart | data: 1–10 label/value pairs; optional unit and blocks |
Content blocks
Blocks are plain text, not Markdown or HTML. Images need alt text and may use HTTP(S) URLs, relative paths, or base64 raster data URLs.
{ "type": "paragraph", "text": "One clear idea." }
{ "type": "bullets", "items": ["First", "Second"], "ordered": false }
{ "type": "image", "src": "assets/diagram.svg", "alt": "Workflow diagram", "caption": "Optional" }
Minimal deck
Schema limits are data limits, not a promise that content fits a slide. Check the rendered layout separately.
{
"metadata": { "title": "Team update", "lang": "en" },
"theme": "light",
"slides": [
{
"layout": "content",
"title": "This week",
"blocks": [
{ "type": "paragraph", "text": "The first milestone is complete." },
{ "type": "bullets", "items": ["Review", "Refine", "Export"] }
],
"notes": "Discuss the next milestone."
}
]
}