Skip to main content

Slide as Code

info

Slide as Code lets you author RevealJS presentations in YAML, Markdown, or HTML — and output self-contained HTML files where all assets (images, styles, scripts) are embedded, ready to share or deploy.

See example slide decks built with Dinghy.

Simple setup

tip

One folder equals one presentation. A single slide.yml is all you need to get started.

Slides are organised under a slides/ directory. Each sub-folder is one presentation, driven by a slide.yml file.

Project layout

slides/
slides.yml ← global config (theme, plugins, …)
my-talk/ ← one folder = one presentation
slide.yml ← sections and per-slide config
*.yml / *.md / *.html / *.css / favicon.* ← auto-loaded, sorted by filename
imgs/ ← images referenced in slides
output/
slides-dist/ ← built output

Create a presentation

mkdir -p slides/my-talk
slides/my-talk/slide.yml
title: My First Presentation
sections:
- badge: Hello
title: My First Presentation
subtitle: Author in YAML — output self-contained RevealJS HTML.

- title: What We Will Cover
ul:
li:
- Topic one
- Topic two
- Topic three

Serve in development

dinghy slide start

Preview in browser

By visiting http://localhost:3000

Slide commands

Authoring

Auto-loading

Individual .yml (excluding slide.yml), .md, .html, .css, and favicon.* files placed in the presentation folder are auto-loaded as sections, sorted alphabetically by filename. Use a numeric prefix to control order:

my-talk/
01-intro.md
02-demo.yml
03-conclusion.html
favicon.svg

YAML DSL

Any YAML key becomes an HTML element. Common keys:

KeyOutput
title<h2>…</h2>
subtitle<p class="subtitle">…</p>
badge<div class="badge">…</div>
p<p>…</p>
h3<h3>…</h3>
notes<aside class="notes">…</aside>
ul/olunordered or ordered list
imgsingle image (r-stretch)
gridside-by-side grid of elements
videobackground video (contain, muted)

Built-in attributes — id, class, style, src, href, alt — map directly to HTML attributes. Keys containing - (e.g. data-*, aria-*) are always treated as attributes.

slides/my-talk/slide.yml
sections:
- class: highlight
id: intro
data-background-color: '#1a1a2e'
title: Styled Slide

Images

# Single image — r-stretch applied automatically
- img: imgs/photo.jpg

Video

When video is a string, it sets the section background to a muted, contained video. The background video plays silently as a visual backdrop. Click anywhere on the slide to open the video in a lightbox where sound is played and playback is fully controllable (play, pause, seek, volume).

# Background video — click anywhere to open lightbox with sound
- video: skill-demo-oss.mov

# With other content overlaid on the background video
- video: skill-demo-oss.mov
title: Demo Time

This is a shorthand for:

- data-background-video: skill-demo-oss.mov
data-background-size: contain
data-background-video-muted: true

When there are no other content keys, a full-slide clickable overlay is added so clicking the slide opens the video in the lightbox with full playback controls. When other content keys are present (e.g. title, p), they render normally on top of the background video.

For additional customisation (e.g. looping, autoplay with sound, custom sizing), use the standard RevealJS video attributes directly:

- data-background-video: skill-demo-oss.mov
data-background-size: cover
data-background-video-loop: true

Grid

Arrange any elements side-by-side in a grid:

- grid:
- img: imgs/a.jpg
- div: anything
- img: imgs/c.jpg

Markdown sections

Drop a .md file into the presentation folder — it is auto-loaded as a section. Or inline with type: markdown:

- type: markdown
markdown: |
## Markdown Slide 1

- item 1
- item 2

---
## Markdown Slide 2

![alt](image.png)

Raw HTML & CSS

Drop .html or .css files into the folder — they are auto-loaded (sorted by filename). Or inline:

- html: '<section><p>Custom <strong>HTML</strong></p></section>'

CSS files become <style> blocks.

Zoom and Pan

Dinghy includes a Prezi-style zoom-and-pan feature built on RevealJS auto-animate. It lets you zoom into regions of a large image across multiple slides, with smooth morphing transitions.

Basic usage

Declare a section with an img, width, height, and a list of sections — each describing a rectangular region to zoom into:

- img: sequence-diagram.png
width: 2077
height: 2096
sections:
- id: dinghy-engine-engine
x1: 922
y1: 80
x2: 1215
y2: 1279
- id: dinghy-engine-drawio
x1: 922
y1: 80
x2: 1529
y2: 1598

Each region becomes its own slide. RevealJS auto-animate handles the transition — the image pans and zooms smoothly from one region to the next.

By default the first slide shows the full image before zooming in. Set skip-full-view: true to go straight to the first region:

- img: sequence-diagram.png
width: 2077
height: 2096
skip-full-view: true
sections:
- x1: 922
y1: 80
x2: 1215
y2: 1279

Region options

KeyDescription
x1Left edge of the region (pixels in the original image)
y1Top edge of the region
x2Right edge of the region
y2Bottom edge of the region
titleOptional HTML title shown centered over the region, disappear after 2 seconds
idOptional HTML id for the generated section
overlayCSS for the highlight box (overrides the section default)

Overlay highlight

While the full image is visible, each region is highlighted with a semi-transparent overlay box. The default is a green tint. Customise it at the section level (applies to all regions) or per region:

- img: sequence-diagram.png
width: 2077
height: 2096
overlay: 'background:rgba(154,62,62,0.2);border:2px solid red;'
sections:
- id: dinghy-engine-drawio
x1: 922
y1: 80
x2: 1529
y2: 1598
- x1: 167
y1: 80
x2: 702
y2: 452
overlay: 'background:rgba(154,62,62,0.2);border:2px solid blue;'
title: '<span style="color: red;">Highlighted area</span>'

Configuration

Global config (slides/slides.yml)

Applies to all presentations in the project:

slides/slides.yml
theme: white
transition: fade
slides:
my-talk2:
title: My Talk 2
sections:
- title: Chapter 1
p: 'Navigate down ↓'
sections:
- title: '1.1 — Introduction'
- title: '1.2 — Details'

These options are only valid at the global level and are not forwarded to RevealJS.

KeyDescriptionDefault
generateSlidesIndexGenerate an index page listing all presentationstrue
trailingSlashAppend a trailing slash to generated URLsfalse
inlineAssetsEmbed all assets in the output HTML filetrue

Per-presentation config (slide.yml)

Override global settings for a single presentation:

slides/my-talk/slide.yml
title: My Talk
config:
theme: moon
transition: fade
slideNumber: 'c/t'
sections:
- title: My Talk

RevealJS config options

These options are valid in both slides/slides.yml (global) and slide.yml (per-presentation under a config: key).

For the complete list see the RevealJS config reference.