The Problem
I needed PDF versions of my Reveal.js slide decks - for student handouts and accessibility. The slides look great in the browser, but getting them into PDF is surprisingly painful.
Reveal.js has a built-in export: append ?print-pdf to the URL, then use Chrome’s print dialog. In practice, this means manually setting landscape orientation, zero margins, and enabling background graphics every time. Miss one setting and the output is broken. Even when you get it right, slides overlap, content splits after titles instead of fitting the page, and it only works reliably in Chrome.
Quarto doesn’t help either - there’s no quarto render --to pdf for revealjs format. The official guidance is the same manual browser workflow. There’s an open issue requesting better tooling, filed under “Future” with no timeline.
I needed something automatable that captures slides as they actually appear.
The Solution: Decktape
Decktape takes a different approach entirely. Instead of relying on a print stylesheet, it drives a headless Chrome instance, navigates through each slide, and captures them individually as PDF pages. What the browser renders is what you get.
Install
No install required - npx runs it directly (like uvx for Python tools):
npx decktape <url> output.pdfIf you use it often enough to want it permanent:
npm install -g decktapeUse
Point it at any URL serving a presentation:
decktape https://example.com/slides output.pdfDecktape auto-detects Reveal.js (and other frameworks) so you don’t need to specify a plugin. No print dialog, no manual settings.
For local development with Quarto:
# Start your presentation (note the port in the output)
quarto preview presentation.qmd
# In another terminal
decktape http://localhost:4567/presentation.html output.pdfWhy It’s Better
- Captures exactly what the browser renders - styling, margins, and aspect ratio are preserved
- Scriptable: no manual print dialog, works in CI
- Control over output resolution via
--size(the print stylesheet gives you no such option) - Works in headless environments where there’s no browser to click through
Useful Options
# Specify output resolution (default is 1280x720)
decktape --size 1920x1080 http://localhost:4567/presentation.html output.pdf
# Add pause between slides for heavy renders (Mermaid diagrams, etc.)
decktape --pause 2000 http://localhost:4567/presentation.html output.pdf
# Export specific slides
decktape --slides 1-10 http://localhost:4567/presentation.html output.pdfFragments (incremental builds) are collapsed by default - each slide renders with all fragments visible. To get one page per fragment step, append ?fragments=true to the URL.
Beyond Your Own Slides
Decktape works on any URL serving a supported presentation framework - not just your own. Useful for archiving conference talks, saving training materials, or capturing content that’s hard to get otherwise.
Resources
- Decktape GitHub
- Quarto Reveal.js presenting guide (includes the manual PDF export workflow)
- Quarto issue #4677 - native PDF export tooling request
- Clean TeX Setup on macOS (for document PDFs instead of presentation PDFs)