Skip to content

Layouts and slots

A slide’s layout decides how its content is arranged. Set it in the slide’s frontmatter:

---
layout: section
---
# Part two: the coast

The first slide defaults to cover and every other slide to default. Set a layout for every slide with defaults: { layout: center } in the headmatter, and the slide’s own key still wins.

Layout What it does
default content from the top left, inside the theme’s padding
center everything centred on both axes
cover the title slide: a large title, subtitle and author
intro an introduction: who you are and what the talk covers
section a divider: one big heading that starts a part of the talk
end the closing slide
fact one number or fact, very large, with a line of context
quote a quotation, set large, with its source
statement one statement, centred and large
full content edge to edge with no padding: a full-bleed picture, map or diagram
none no wrapper at all: the slide’s MDX is the slide
two-cols two columns: everything before ::right:: on the left, the rest on the right
two-cols-header a header across the top, then ::left:: and ::right:: side by side, and an optional ::bottom::
image a picture (image:) filling the slide, the content over it
image-left a picture filling the left half, the content on the right
image-right the content on the left, a picture filling the right half
iframe a live web page (url:) filling the slide, loaded only while the slide is near
iframe-left a page on the left half, the content on the right
iframe-right the content on the left, a page on the right half

npx kadal-deck info layoutspnpm exec kadal-deck info layoutsyarn kadal-deck info layoutsbunx kadal-deck info layouts prints the same list, with the keys each one reads.

A layout with more than one region takes slots. A line ::name:: starts the slot called name; everything before the first marker is the default slot.

---
layout: two-cols
---
# Before
The old way: three tools, two exports.
::right::
# After
One file, one command.

two-cols-header puts what comes first across the top, then the two columns, then an optional ::bottom:: across both again:

---
layout: two-cols-header
---
# Two ways to publish
::left::
**Hosted:** `npx kadal-deck publish`, and the deck has a live room.
::right::
**Anywhere:** `npx kadal-deck build`, and `dist/` goes on any static host.
::bottom::
Both start from the same `deck.mdx`.

Slot markers must sit on a line of their own, with blank lines around them.

The image* layouts read image: (a file in public/ or a URL) and backgroundSize (default cover); the iframe* layouts read url:.

---
layout: image-right
image: /photos/harbour.jpg
---
# Chennai harbour
High water came 40 minutes after the Moon said it would.
---
layout: iframe-right
url: https://example.com
---
# The live map
Click the page to use it; **Done** gives the keys back to the deck.

An embedded page loads when its slide is near and unloads when you leave. In print, the overview and the next-slide preview, a poster stands in for it: poster: names a picture, or kadal-deck export photographs the page for you. See Export.

On Pro and Team, the Pro library adds designed layouts: magazine covers, pitch covers, KPI boards, agendas, pull quotes, comparison splits and more, each with its own art and drawn for light and dark. They take a pro/ name and use the same slots as the built-ins:

---
layout: pro/folio-split
kicker: Chapter two
---
# A headline
Body text.
::right::
![](/photo.jpg)

Each layout’s slots and frontmatter keys are in its detail sheet under Explore → Layouts in the dashboard. Like the Pro backgrounds they render on our hosting only; anywhere else a pro/ layout falls back to default, so the slide’s content still shows. See Pro backgrounds and layouts.

A theme can add layouts of its own. The gallery shows each theme’s, and npx kadal-deck info themespnpm exec kadal-deck info themesyarn kadal-deck info themesbunx kadal-deck info themes lists the ones installed in your deck. A few:

Theme Adds
brand title-logo, agenda, metrics
lecture section (numbered), definition, theorem, references
folio pull-quote, essay, chapter
swiss poster, index, grid
terminal code, shell
crisp intro-image, intro-image-right, image-right, 3-images, bullets

A theme’s layout with a built-in name replaces the built-in while that theme is in use.

A layout is a React component. Register it in src/components.tsx under a layout: name:

src/components.tsx
import type { LayoutProps } from "@kadal/deck";
import type { ComponentType } from "react";
function Agenda({ frontmatter, children }: LayoutProps) {
const eyebrow = typeof frontmatter.eyebrow === "string" ? frontmatter.eyebrow : "Agenda";
return (
<div className="deck-layout deck-layout-agenda">
<p className="agenda-eyebrow">{eyebrow}</p>
{children}
</div>
);
}
export const components: Record<string, ComponentType<Record<string, unknown>>> = {
"layout:agenda": Agenda as unknown as ComponentType<Record<string, unknown>>,
};
---
layout: agenda
eyebrow: Today
---
1. The Moon
2. The Sun
3. The coast

The layout receives the slide’s frontmatter (so it can read keys of your own, like eyebrow here), its options, and the content as children. Wrap them in an element with the deck-layout class and one of your own. Slots arrive inside children as <div class="deck-slot deck-slot-<name>">, so a layout places them with CSS:

src/styles.css
.deck-layout-agenda { display: grid; gap: 24px; }
.deck-layout-agenda .deck-slot-right { justify-self: end; }

To share a layout across decks, put it in a theme or an addon.

Send feedback