Embedding
Every published demo has a share link (/d/:slug) and two ways to embed it on a page you control.
The script snippet (default)
Paste a <div data-mado> and one script tag. The loader finds every [data-mado] on the page, so multiple demos on one page only need the script once. It mounts lazily (an IntersectionObserver), reserves its final box before the demo loads so nothing shifts, and never sets a cookie.
<div data-mado="your-demo-slug"></div>
<script async src="https://mado.show/p/loader.js"></script>Optional attributes on the same element:
data-aspect="9:19.5"— the capture's aspect ratio, if you want to reserve the box before the loader has a chance to read it from the document.data-poster="…"— an image painted before the player loads.data-step="s7"— open on a specific step (see deep-linking below).data-inline="true"— mount the player as a web component directly in your page's DOM instead of a sandboxed iframe.data-autoplay="true"— the demo plays itself (watch mode) once it scrolls into view, and pauses when it scrolls out or the tab is hidden. Any tap, key or scroll on it hands control to the visitor. Off by default; the Watch button in the player is always there. On a share link or the iframe URL, the same thing is?play=1.data-edition="phone"ordata-edition="desktop"— for a demo that has a phone edition (its own steps and lines, written for a phone), force which one plays. Without it, a portrait box narrower than 600px gets the phone edition and every other box the desktop one; a demo without a phone edition ignores it. On a share link or the iframe URL, the same thing is?edition=phone.data-phone="tall"ordata-phone="poster"— how a landscape demo looks on a phone (a screen narrower than 640px). Without it, the demo keeps its own shape, which on a phone is a short box.tallreserves a taller box, so text is readable.postershows a picture with a button that opens the demo in a new tab; nothing loads and no view is counted until it is opened. A demo of a phone app keeps its own shape, and so does every demo on a wider screen.data-watch="true"— adds a “Watch the full demo” link under the embed, which opens the share page in a new tab. The snippet copied from Studio already contains the link, right after the<div>, so the page does not move when the loader arrives; the loader only adds one when it is not there.data-for="acme"— a label for a person or company, so this embed's views show under that name in analytics.data-vars='{"company":"Acme"}'— personalisation values for the demo's{company}placeholders.
The iframe fallback below has no loader, so data-phone and data-watch do not apply to it.
The iframe fallback
Some CMS and docs editors strip <script> tags. This form needs none — it's a plain sandboxed iframe reserving the same aspect-ratio box the loader would.
<div style="position:relative;aspect-ratio:9/19.5;overflow:hidden;border-radius:12px">
<iframe src="https://mado.show/e/your-demo-slug" title="Interactive demo" loading="lazy"
allow="clipboard-write; fullscreen"
sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"
style="position:absolute;inset:0;width:100%;height:100%;border:0"></iframe>
</div>Deep-linking a step
Every step is addressable. Append ?s=s7 to a share link, or set data-step / the iframe's query string, to open a demo on that exact step instead of the start. This is what lets a help-center article link straight to the relevant part of a walkthrough.
By platform
The two forms above cover every host. Here is exactly where to paste them in the tools people ask about most.
Notion
- Type `/embed` on a line and choose the Embed block.
- Paste your share link (`https://mado.show/d/your-demo-slug`) or the raw iframe target (`https://mado.show/e/your-demo-slug`) and confirm.
- Notion sandboxes third-party embeds itself, so the iframe form is the only one that works here — there is nowhere to paste a `<script>` tag.
Webflow
- Add an Embed element from the Add panel (under Components, Embed) wherever the demo should sit.
- Paste the script snippet below into it and publish the page.
- Webflow renders Embed elements as-is, script tag included, so either snippet works — the script version keeps the lazy-load and no-layout-shift behavior.
<div data-mado="your-demo-slug"></div>
<script async src="https://mado.show/p/loader.js"></script>Framer
- Drag in an Embed component from Insert, under Embed.
- Switch it to “HTML” mode and paste the script snippet, or leave it in “URL” mode and paste `https://mado.show/e/your-demo-slug` directly.
- Framer’s URL mode wraps the address in its own iframe automatically — no snippet needed at all in that mode.
WordPress
- Add a Custom HTML block (Gutenberg) or an HTML box (Classic Editor / Elementor) and paste a snippet below.
- Self-hosted WordPress and Business-plan WordPress.com sites allow the script snippet in a Custom HTML block. Free and Personal WordPress.com plans strip `<script>` tags — use the iframe snippet there instead.
Works on every plan
<div style="position:relative;aspect-ratio:9/19.5;overflow:hidden;border-radius:12px">
<iframe src="https://mado.show/e/your-demo-slug" title="Interactive demo" loading="lazy"
allow="clipboard-write; fullscreen"
sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox"
style="position:absolute;inset:0;width:100%;height:100%;border:0"></iframe>
</div>Ghost
- Add an HTML card (type `/html` in the editor) and paste a snippet below.
- Ghost renders card HTML as written, so either snippet works.
<div data-mado="your-demo-slug"></div>
<script async src="https://mado.show/p/loader.js"></script>Plain HTML
- Paste the script snippet anywhere in your page’s markup — no build step, no framework.
- If your CMS or CSP strips inline `<script>` tags, use the iframe fallback instead.
<div data-mado="your-demo-slug"></div>
<script async src="https://mado.show/p/loader.js"></script>Every share page's Embed panel (/d/:slug) already has your demo's slug baked into both snippets — copy from there and paste it straight into whichever of these you're using.