Skip to main content

Embedding a demo

There are two ways to put a Showdini demo on your site:

  • A plain iframe — no JavaScript, works anywhere, including site builders that only allow an HTML block.
  • The embed widget — a small script that renders the demo inline and expands it to a fullscreen modal when the call starts.

Both need your demo ID, and both accept the same URL parameters. If you have not embedded a demo before, start with the Quickstart — this page covers the options once it works.

To send visitors to the demo instead of hosting it yourself, see Sharing a demo link.

Inline embed​

Use this when the demo should always be visible on the page.

Every embed needs allow="microphone; autoplay"

The demo is a voice conversation. Without that attribute the browser blocks microphone access and the visitor cannot talk to the agent. The page also has to be served over HTTPS — localhost counts while you develop.

<section>
<h2>Interactive Demo</h2>
<iframe
src="https://demo.showdini.ai/start/YOUR_DEMO_ID?embedded=true"
allow="microphone; autoplay"
allowfullscreen
style="width: 100%; height: 720px; border: none; border-radius: 12px;"
></iframe>
</section>

Embed widget​

The widget renders the lobby inline inside your container. When the visitor starts the call it expands to a fullscreen modal, then collapses back to the lobby when the call ends.

Every option below has a working, clickable version on the live examples page.

<!-- 1. Size the container however you want -->
<div id="demo-container" style="width: 380px; height: 560px"></div>

<!-- 2. Load the widget and init -->
<script src="https://embedded.showdini.ai/showdini-embed.js"></script>
<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
container: "#demo-container",
});
</script>

The iframe lazy-loads the first time the container scrolls into view. To defer loading until a button is clicked instead, pass a trigger:

<button id="open-btn">Watch Demo</button>
<div id="demo-container" style="height: 560px"></div>

<script src="https://embedded.showdini.ai/showdini-embed.js"></script>
<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
container: "#demo-container",
trigger: "#open-btn", // selector, Element, or an array of either
});
</script>

Without a container, Showdini.init runs in modal mode: a trigger opens a centered modal.

Ask bar​

Instead of (or alongside) a button, the widget can render an ask bar on your page — a How can I help? text input. Focusing it opens the demo straight away, so the bar is a click-to-chat affordance: the input is read-only.

<script src="https://embedded.showdini.ai/showdini-embed.js"></script>
<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
launcher: true, // or an options object, see below
});
</script>

By default the input types out a rotating set of generic questions, so the bar shows what the agent can be asked rather than sitting silent. Replace them with questions your own demo answers well — that is the one thing worth customising here:

<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
launcher: {
placeholder: [
"What does the onboarding look like?",
"How does billing work?",
"Show me the reporting",
],
},
});
</script>

A single string turns the animation off: placeholder: "Ask about pricing". The typing pauses while the demo is on screen and stops entirely for visitors who ask for reduced motion, who see the first question only.

The bar floats at the bottom of the page. Pass mount to place it in your own layout instead, and ctaLabel to relabel the button:

<div id="ask-bar"></div>

<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
launcher: {
mount: "#ask-bar",
placeholder: ["Show me a tailor", "Find me a suit", "Book a fitting"],
ctaLabel: "Watch Now",
buttonColor: "#615CF6",
buttonTextColor: "#ffffff",
},
});
</script>
launcher optionTypeDescription
placeholderstring | string[]Question(s) the input suggests. An array types them out in turn; a single string sits still. Defaults to a generic set.
mountstring | ElementRender the bar inside this element. Omit to float it.
positionstringbottom-center (default), bottom-left or bottom-right. Floating bars only.
logoUrlstringSmall round logo shown inside the bar, at the left. Hidden when omitted.
ctaLabelstringLabel of the button inside the bar. Defaults to Instant chat; pass "" to leave just the input.
buttonColorstringBackground colour of the CTA button. Any CSS colour. Defaults to Showdini purple (#615CF6).
buttonTextColorstringColour of the CTA button's label. Defaults to #ffffff — set it when buttonColor is light.
themestringlight (default) or dark. Pick whichever suits the page.
dismissiblebooleanShow a close button on the bar. Defaults to false.

A floating bar steps aside while the demo is on screen and comes back when the demo closes. A mounted bar stays where you put it.

dismissible adds a close button. Closing takes the bar off the page and is remembered per demo for the rest of the visitor's browsing session (sessionStorage), so it does not come back on the next page they open. Where storage is unavailable — private mode, cookies blocked — the bar simply returns on the next page view.

The bar itself collects no text — it opens the demo and the visitor talks to the agent there.

Fitting your page​

The bar is one rounded surface — input, optional logo and optional button inside it — and is deliberately plain so it sits on most designs unchanged. Two things worth knowing:

  • It brings its own styles. Every element in the bar is reset and restyled, so host page rules for bare input, button or div selectors cannot leak in and distort it. A rule with !important on one of those selectors still wins, so avoid those.
  • It does not follow the visitor's OS theme. theme: "dark" is opt-in, so a light site never ends up with a dark bar because of a visitor's system setting.
  • Width. A floating bar is 560px wide on desktop and spans the viewport minus a 12px gutter below 720px. A mounted bar sizes to its own content, so your own CSS on the mount element decides how wide it gets.
<script>
Showdini.init({
demoId: "YOUR_DEMO_ID",
launcher: { theme: "dark", ctaLabel: "Instant Chat" },
});
</script>

Respecting prefers-reduced-motion, the bar's hover and fade transitions are dropped for visitors who ask for that.

Showdini.init options​

OptionTypeDescription
demoIdstringRequired. Your Showdini demo ID.
containerstring | ElementMount the demo inline in this element. Omit for modal mode opened by a trigger.
triggerstring | Element | arrayElement(s) that open the demo. In inline mode, defers loading until clicked.
closeTriggerstring | Element | arrayElement(s) that close or collapse the demo.
width / heightstringSize of the expanded modal. Defaults to 95% / 95%. Inline size comes from the container.
metadataobjectKey/value data attached to the lead. See Metadata.
forwardPageParamsbooleanAlso capture utm_* / gclid and similar from the host page's URL. Defaults to false.
launcherboolean | objectRender an ask bar on your page. See Ask bar.

Custom modal​

Use this when you want to open the demo from your own button but keep the integration iframe-based.

<button id="open-btn">Open Demo</button>

<div id="my-modal" style="display:none; position:fixed; inset:0; z-index:9999;
background:rgba(0,0,0,.5); align-items:center; justify-content:center;">
<div style="position:relative; width:90%; height:90%; background:#fff;
border-radius:12px; overflow:hidden;">
<button id="my-modal-close" style="position:absolute; top:10px; right:14px;
z-index:1; font-size:20px; background:none; border:none; cursor:pointer;">
&#x2715;
</button>
<iframe
id="demo-iframe"
src=""
allow="microphone; autoplay"
allowfullscreen
style="width:100%; height:100%; border:none;"
></iframe>
</div>
</div>

<script>
var modal = document.getElementById("my-modal");
var iframe = document.getElementById("demo-iframe");

document.getElementById("open-btn").addEventListener("click", function () {
if (!iframe.src) {
iframe.src = "https://demo.showdini.ai/start/YOUR_DEMO_ID?embedded=true";
}
modal.style.display = "flex";
});

document.getElementById("my-modal-close").addEventListener("click", function () {
modal.style.display = "none";
iframe.src = "";
});
</script>

Clearing iframe.src on close ends the call and releases the microphone.

URL parameters​

Add parameters to the query string of the iframe src to change how the demo opens:

https://demo.showdini.ai/start/YOUR_DEMO_ID?embedded=true&lang=en&mail=jordan@acme.com
ParameterRequiredDescription
embeddedYesSet embedded=true whenever the demo runs inside a frame.
langNoLanguage the demo opens in, as a two-letter code (e.g. fr, ja). Defaults to the demo's own default language. See Languages.
flangNoForces the visitor to choose a language before the demo starts.
mailNoPrefills the email field.
meta_*NoAttaches your own data to the lead, prefix stripped. See Lead metadata.
utm_*, gclid, …NoWell-known tracking parameters, captured automatically. See Lead metadata.

Unrecognised parameters are ignored, so it is safe to leave your own analytics tags on the URL.

embedded​

Switches the demo to its embedded layout, which drops the full-page chrome so it sits properly inside your frame. Leaving it off gives the visitor a full-page demo squeezed into your iframe, which looks cropped.

lang and flang​

lang picks the starting language. flang instead makes the visitor choose before anything begins — useful when one demo serves audiences in several languages and guessing wrong is worse than asking.

If you set both, the visitor still gets the language picker; lang only decides what is preselected.

lang takes any supported language code. The conversation runs in all of them; the demo interface is translated for English and Slovenian only, and the agent switches language on its own if the visitor speaks a different one.

mail​

Prefills the email field so the visitor does not retype an address you already have. It does not skip the step or verify the address — the visitor can still edit it before starting.

The embed widget builds the URL for you

If you use the embed widget rather than a raw iframe, do not build the query string yourself. Pass metadata through Showdini.init instead, and set forwardPageParams: true to capture tracking parameters from the host page.

What's next?​

  • For attaching your own data to the lead, such as a CRM record id or a partner code, see Lead metadata.
  • For receiving the finished lead on your own endpoint, see Webhooks.