MDX slides
A deck is one MDX file. MDX is Markdown that can hold JSX, so everything Markdown does works, and any component the engine ships — or that you write — can sit between paragraphs.
Separators
Section titled “Separators”---title: My talktheme: minimal---
# The first slide
---
## The second slide, one column to the right
---
### A vertical slide, below the second---starts a new slide, one column to the right.----starts a vertical slide beneath the previous one (reveal.js’s vertical stacks). Arrow keys walk the steps first, then the column; ↓/↑ move within a stack.
Headmatter and frontmatter
Section titled “Headmatter and frontmatter”The YAML block at the very top is the headmatter: deck settings (title, author, theme,
transition, slideNumber, defaultTiming, …) and, at the same time, the frontmatter of the first
slide. deck.config.ts overrides the headmatter, which overrides the defaults; every option is in the
configuration reference.
YAML between two --- separators is that slide’s frontmatter:
---layout: two-colsbackground: auroratransition: fadeclass: hero---Per-slide keys:
| Key | Meaning |
|---|---|
layout |
the slide’s layout (below); the first slide defaults to cover, the rest to default |
class |
CSS classes on the slide (a string or a list) |
background |
a colour, a gradient, an image, a video, an iframe, or a background component — see Themes and backgrounds |
transition, transitionSpeed, backgroundTransition |
override the deck’s transition for this slide |
colorScheme |
dark or light: force tokens on this slide (a dark background under a light theme) |
clicks |
the slide’s total steps, when it can’t be counted from its content |
clicksStart |
the step the slide opens at |
autoAnimate, autoAnimateId, autoAnimateRestart |
animate matching elements between consecutive slides |
autoSlide |
milliseconds before this slide advances on its own |
timing |
seconds this slide should take, for the pacing timer |
hide |
leave the slide out of the deck (visibility: hidden does the same; visibility: uncounted keeps it but skips it in numbering) |
hideInToc |
leave it out of <Toc> |
zoom |
scale the slide’s content |
state |
names added to the deck while this slide is shown |
preload |
false to load the slide only when reached |
poster, posterUrl, posterWait |
the stand-in image for an embedded page — see Export |
terms |
false, or { skip: [...] }, for glossary linking on this slide |
Layouts
Section titled “Layouts”default, center, cover, intro, section, end, fact, quote, statement, full, none,
two-cols, image, image-left, image-right, iframe, iframe-left, iframe-right.
Layouts with more than one region take slots. A line ::name:: starts the slot called name:
---layout: two-cols---
# Left column
The default slot.
::right::
# Right columnRegister your own layouts in src/components.tsx with a layout: prefix — "layout:agenda": Agenda
— and use them as layout: agenda.
<Notes>Start with the poll. [click] Then reveal the first point. [click] And the second.</Notes>The presenter view splits notes at [click]: segment N is highlighted exactly when the slide is at
step N, so the notes keep pace with your clicks. Notes are compiled to their own module and never
load on the audience’s screens unless you share them.
Your own components
Section titled “Your own components”Anything exported from src/components.tsx is available in deck.mdx without an import:
export const components = { Price: ({ amount }: { amount: number }) => <strong className="price">${amount}</strong>,};It costs <Price amount={4} /> a month.Cards that share a row share a height: a <Glass> or <Callout> that is the only thing in its
<Col> fills the cell, unless the row says align="start". Give your own card component the
deck-card class to join in.
Built-in components
Section titled “Built-in components”| Group | Components |
|---|---|
| Layout | Cols/Col, Grid, Absolute, Transform, FitText |
| Content | Callout (kind="info" | "tip" | "warn" | "danger" | "note"), Badge, Kbd, Mark, Arrow, Toc, Qr |
| Motion | Counter, Typewriter, Encrypted, FlipBoard, Motion, Confetti, Timer |
| Media | image preview (click to enlarge), Youtube, Tweet, Iframe |
| Bling | GradientText, Glass, Glow, Chip, Icon (any Lucide icon), Divider, Ribbon, Halo, Shimmer, Blob, Tilt |
| Live | QrJoin, Presence, Reactions, Poll, WordCloud, Quiz, Leaderboard, Questions, Pace — see The live room |
Bling components read the theme’s tokens and take a tone: accent, accent-2, good, warn,
bad, info, neutral, purple, pink, amber, teal.
Embedded pages
Section titled “Embedded pages”layout: iframe* and <Iframe> load a page when its slide shows and unload it when you leave. A
“click to interact” shield keeps your keys driving the deck until you mean to use the page; Done
hands the keyboard back. The next slide’s pages are already loading, hidden, so arriving there looks
instant. <Iframe scale={0.5}> renders a page at twice the pane and shrinks it — a desktop layout in a
small card.
The same slide everywhere
Section titled “The same slide everywhere”The stage is authored at 1920 × 1080 (width/height) and scaled uniformly to every window: edge to
edge on a 16:9 screen, centred between bars on a phone, a tall window or a 4:3 projector — never
reflowed. A slide whose content overflows is scaled down to fit (autoFit, on by default).