Docs Documentation
Present your own HTML deck
No laptop? Upload your presentation as one HTML file: the screens play it and your phone changes the slides.
A presenter does not need a laptop to show slides. Upload your presentation as one self-contained HTML file on your presenter link. When your session is live, every screen of the session plays it where the screen share would be, and the page on your phone becomes your remote — the slide number, the title, your notes, and a touchpad to swipe through.
For the speaker
- Open your presenter link. Under Your presentation, press Upload and choose the file (up to 25 MB). It is shown instead of a screen share straight away; the switch Show it instead of a screen share turns that off and on.
- Before your talk, open the link on your phone and press Join backstage. You do not need the camera or the microphone for this.
- When the operator puts you on, swipe left for the next slide and right for the previous one, or tap the right or left half of the pad. Back, Start and Next do the same. Your notes for the current slide appear under the pad.
A new version? Press Replace and choose the file again. The screens load it by themselves, and your phone puts the deck back on the slide you were on — the same happens when a screen restarts in the middle of your talk.
Hands free. In the remote on a phone, the hand button turns on hand signs through the phone's camera: thumb up, held for half a second, for the next slide, a victory sign to go back. Each sign counts once — lower your hand before you show it again. Choose the front or back camera and whether the phone lies near you or across the stage. Talking with your hands does not count. Try it where you will stand: it depends on the light and the distance, and the touchpad always works.
For the deck author — the deck protocol
Any HTML presentation can be driven from the phone if it speaks the deck protocol (version 1): plain messages over window.postMessage, tagged wf: 'deck'. Outside Wunderframe nothing changes — keyboard and clicks keep working.
- Commands in:
{ wf: 'deck', v: 1, cmd: 'next' }— and'prev','first','last','hello';{ wf: 'deck', v: 1, cmd: 'goto', index }with a 0-based slide index. - State out: after every change, post
{ wf: 'deck', v: 1, state: { index, count, title, notes } }towindow.parentwith the target origin'*'(the frame is sealed, its origin is opaque).indexis 0-based;titleandnotesare plain text for the phone. - Loaded: the first state you post carries
ready: true; answerhellowith the state. - Only act on messages whose
wfis'deck'. You can tell you are on a screen bywindow.parent !== window.
const embedded = window.parent !== window;
let current = 0, first = true;
const slides = [...document.querySelectorAll('section')];
function show(i) {
current = Math.max(0, Math.min(slides.length - 1, i));
slides.forEach((s, n) => (s.hidden = n !== current));
report();
}
function report() {
if (!embedded) return;
const s = slides[current];
window.parent.postMessage({ wf: 'deck', v: 1, state: {
index: current, count: slides.length,
title: s.dataset.title ?? '', notes: s.dataset.notes ?? '',
...(first ? { ready: true } : {})
} }, '*');
first = false;
}
window.addEventListener('message', (e) => {
const m = e.data;
if (!m || m.wf !== 'deck') return;
if (m.cmd === 'next') show(current + 1);
else if (m.cmd === 'prev') show(current - 1);
else if (m.cmd === 'first') show(0);
else if (m.cmd === 'last') show(slides.length - 1);
else if (m.cmd === 'goto' && Number.isInteger(m.index)) show(m.index);
else if (m.cmd === 'hello') report();
});
show(0);Making one file. A deck built with a bundler becomes one file with an inlining step — for Vite, vite-plugin-singlefile plus assetsInlineLimit set high, and fonts added as @font-face rules with data: URLs. Screens in venues are often old: build for Safari 14 (build.target: 'safari14') and test the file by opening it straight from your disk with the network switched off.
The picture. The deck fills the presenter block it replaces and scales itself to it — design on a fixed canvas (for example 1920 × 1080) and scale that to the window, the way a slide deck does.