| name | deck-add-slide |
| description | Guide for adding a new slide to a deck project. Use this when asked to create, add, or build a new slide component. |
Adding a Slide to a Deck Project
Step 0 — Resolve the descriptor and design system
Read .github/instructions/descriptor-resolution.instructions.md first. It tells you how to pick the right theme descriptor, how to cross-check designSystem, and which shadcn supplements to load. Follow the descriptor exactly for slide structure, CSS, tokens, decorative elements, allowed components, and anti-patterns.
Step 1 — Inline editing contract
Also read .github/instructions/inline-editing.instructions.md before writing slide JSX.
- Import
Editable from @deckio/deck-engine for any slide with user-facing copy.
- Import
EditableList from @deckio/deck-engine when the slide renders a list of user content.
- Wrap titles, subtitles, body copy, captions, semantic labels, metrics, badges, list items, quotes, and
BottomBar footer text in <Editable>.
- Wrap any
.map() over a user-content array (cards, bullets, steps, KPIs, features) in <EditableList id="<slide>.<list>" items={…} keyOf={(i) => i.id}>. Each item MUST have a stable id field. Skip EditableList only for decorative arrays (icons, orbs, dots, glyphs).
- Use stable, semantic IDs such as
slideName.title, slideName.items.<itemId>.label, or slideName.footer.
- Do not wrap decorative glyphs, watermarks, fixed counters, icons, or layout-only text.
Step 2 — Create the slide from the descriptor
The descriptor is the source of truth. Read these sections before generating code:
- Exact JSX skeleton
- Exact CSS skeleton
- Token table
- Decorative elements available
- Available components
- Anti-patterns
- Example slide direction
Do not paraphrase the structure if the descriptor gives an exact skeleton. Start from it, then fill in real content.
Step 3 — Registration in deck.config.js
After creating the slide files:
- Add an import at the top:
import MyNewSlide from './src/slides/MyNewSlide.jsx'
- Add the component to the
slides array at the desired position.
- Do not change
theme, designSystem, or aurora while registering the slide.
The generic App.jsx renders slides from this array and passes index automatically. You do not manage slide indices manually.
Step 4 — Common limits and guardrails
These apply regardless of theme:
- Always include
content-frame content-gutter
- Always include
BottomBar as the last child inside <Slide>
- Always wrap
BottomBar text in <Editable as="span" id="slideName.footer">...</Editable> when the footer text is user-facing
- Always wrap user-content
.map() calls in <EditableList> with a stable item id field, and pass a className whose CSS module rule establishes a slide-aware layout that fits within the density limits below (skip only for decorative arrays)
- Always use ESM imports for images and logos
- Never use string paths for images
- Never use
flex: 1 on the body wrapper
- Never add
flex-direction: column on the slide root
- Never overload a slide until it overflows the viewport
Content density limits
| Layout | Max items | Notes |
|---|
| Cards (3-col grid) | 6 (2 rows) | Reduce card padding if tight |
| Cards (2-col grid) | 4 (2 rows) | Preferred for detailed cards |
| Timeline / event list | 3–4 items | Use compact card height for 4 |
| Bullet points | 6–8 | Depends on line length |
| Full-width content blocks | 2–3 | Split across slides if it gets tight |
The <EditableList> container is where these limits become a layout: pass a className whose CSS module rule renders the items as the matching grid/flex layout (e.g. display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem for a 3-col card grid). When no className is provided the engine falls back to a responsive auto-fit minmax(220px, 1fr) grid — safe for cards/features, but compact bullet lists and timelines should always pass their own class.
Step 5 — Verify
After writing the slide:
- Re-read the descriptor and confirm the slide still matches it.
- Run the project validation flow.
- Visually inspect the slide in the deck.
Quick checklist