> For the complete documentation index, see [llms.txt](https://docs.supademo.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.supademo.com/share/embed/in-app-product-tours.md).

# In-App Product Tours

Trigger Supademo demos as in-app product tours with one script: launch demos or Showcases in a modal from any button to onboard users inside your app.

In-app product tours let you launch Supademo demos and Showcases inside your own product, so you can onboard new users, drive feature adoption, and offer contextual training exactly where people need it. With a single script tag, any button, tooltip, or clickable element in your app can open a Supademo in a full-screen modal — and you can also place demos inline in your UI or add a persistent Demo Hub widget.

{% hint style="success" %}
Great for onboarding, feature adoption, and contextual training.
{% endhint %}

![](https://d33v4339jhl8k0.cloudfront.net/docs/assets/65cd1b060e92bd4055f3b684/images/66be7ccf6eb51e63b8f9f06b/file-9ghpuGEZkH.png)

{% hint style="danger" %}
In-app product tours via the Supademo SDK require a Scale, Growth or Enterprise plan.
{% endhint %}

## What are in-app product tours?

An in-app product tour is a Supademo embedded inside your product's UI instead of on a public website — the demo becomes part of your onboarding and help experience for logged-in users. Because Supademo tours are interactive recreations of your product rather than fragile DOM-attached tooltips, you can surface unlimited onboarding demos, product tutorials, or new-feature highlights throughout your app without heavy engineering effort.

Supademo supports three ways to bring demos into your app:

| Method                          | How it works                                                                              | Best for                                                            |
| ------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Modal tours via the SDK (below) | One script tag; a `data` attribute or JavaScript call opens a demo in a full-screen modal | "See how it works" buttons, onboarding checklists, feature callouts |
| Inline in-app placement         | Paste the standard iframe embed code inside your product UI                               | Help centers, empty states, and onboarding screens                  |
| Demo Hub widget                 | A persistent launcher opens a drawer with a curated library of demos                      | Always-available self-serve guidance across your whole app          |

The rest of this page covers each method, how to pass user data into tours, and how to trigger tours without code using Google Tag Manager.

## How to set up in-app product tours with the Supademo SDK

The Supademo SDK is a single script that opens any demo or Showcase in a full-screen modal inside your app. Add the script, initialize it with your workspace API key, then trigger tours from any element or from your own code. You can copy your workspace's pre-filled script and API key from the in-app setup page at [app.supademo.com/tour](https://app.supademo.com/tour).

### 1. Install the SDK

Add this line of code inside your app's `<head>` or `<body>`:

```html
<script src="https://script.supademo.com/script.js"></script>
```

### 2. Initialize the SDK

Initialize Supademo with your API key. If you're using frameworks like React, Angular, Vue, or Svelte, initialize after the DOM is rendered:

**HTML**

```html
<script>
Supademo("YOUR_API_KEY", {
  variables: { email: "", name: "", custom_variable: "" }
});
</script>
```

**React**

```javascript
useEffect(() => {
  Supademo("YOUR_API_KEY", {
    variables: { email: "", name: "", custom_variable: "" }
  });
}, []);
```

**Angular**

```javascript
ngAfterViewInit() {
  //@ts-ignore
  Supademo("YOUR_API_KEY", {
    variables: { email: "", name: "", custom_variable: "" }
  });
}
```

**Vue**

```javascript
mounted() {
  Supademo("YOUR_API_KEY", {
    variables: { email: "", name: "", custom_variable: "" }
  });
}
```

**Svelte**

```javascript
onMount(() => {
  Supademo("YOUR_API_KEY", {
    variables: { email: "", name: "", custom_variable: "" }
  });
});
```

### 3. Trigger a tour via click

Add a `data` attribute to any button or HTML element to open a Supademo or Showcase when it's clicked:

**Trigger a Supademo:**

```html
<button data-supademo-demo="YOUR_DEMO_ID">View Demo</button>
```

**Trigger a Showcase:**

```html
<button data-supademo-showcase="YOUR_SHOWCASE_ID">View Showcase</button>
```

{% hint style="info" %}
You can add the `data-supademo-demo` or `data-supademo-showcase` attribute to any clickable element — buttons, links, tooltips, or icons.
{% endhint %}

### 4. Trigger a tour programmatically

You can also open tours from your own code — from event handlers, feature flags, or product milestones.

**Trigger a Supademo via JavaScript:**

```
Supademo("YOUR_API_KEY").loadDemo("YOUR_DEMO_ID");
```

**Trigger a Showcase via JavaScript:**

```
Supademo("YOUR_API_KEY").loadShowcase("YOUR_SHOWCASE_ID");
```

Replace `YOUR_DEMO_ID` or `YOUR_SHOWCASE_ID` with the ID of your specific Supademo or Showcase — it's the last segment of the URL at `app.supademo.com/demo/[ID]` or `app.supademo.com/showcase/[ID]`.

When a tour opens, the SDK shows a full-screen modal with a dimmed, blurred backdrop and a loading indicator while the demo loads. Viewers can close the tour with the close button, by clicking outside the demo, or by pressing **ESC**. See the full instructions in-app by [visiting this link](https://app.supademo.com/tour), or watch the setup walkthrough:

{% @supademo/embed url="<https://app.supademo.com/demo/clzvwnyj100l9w28q87cf40ir>" demoId="clzvwnyj100l9w28q87cf40ir" %}

## How to pass user data into in-app tours

The Supademo SDK can pass the logged-in user's details into a tour as dynamic variables, so demo text can greet users by name or reference their account. Fill in the `variables` (plus top-level `email` and `name`) fields of the initialization snippet above with your user's real values, and they're applied automatically whenever a tour opens from a `data-supademo-demo` or `data-supademo-showcase` element. When you open a tour programmatically with `loadDemo()` or `loadShowcase()`, pass the variables in that call instead. \[VERIFY: confirm the exact programmatic variables signature with engineering]

Behind the scenes, each variable is appended to the demo's embed URL as a `v_`-prefixed query parameter, the same mechanism used by every embedded Supademo. For how to reference these variables inside your demo's text, see [Variables in Embeds](https://docs.supademo.com/customize/personalize/variables-and-tokens/variables-in-embeds).

## How to place a demo inline inside your app

Inline in-app placement means rendering a Supademo directly inside a screen of your product — an onboarding step, a help panel, or an empty state — instead of opening it in a modal. Use the standard responsive iframe embed code from the demo's **Share → Embed** section, exactly as you would on a website; the full walkthrough is at [Embed a Demo on Your Website](https://docs.supademo.com/share/embed/website-embed).

Inline placement pairs well with the [Embed Events API](https://docs.supademo.com/share/embed/embed-events-api): your app can listen for `postMessage` events from the embedded demo and react when the user progresses or finishes — for example, marking an onboarding checklist item complete when the `Supademo:completed` event fires. This also works if you build your own custom modal around the iframe rather than using the Supademo SDK's built-in one.

## How to add a persistent Demo Hub widget

A Demo Hub is a persistent in-app widget that gives users an always-available library of demos in a slide-out drawer, opened from a floating launcher icon or from your own button. Where a single tour answers one question, a Demo Hub provides standing self-serve guidance across your whole product.

Install it by copying the script shown pre-filled on your Demo Hub's **Install** page — it includes your hub's ID, ready-made snippets for HTML, React, Angular, Vue, and Svelte, and trigger code for opening and closing the drawer from your own buttons. You can restrict which domains the Demo Hub appears on with the **Allowed Domains** setting on the same page, and if your app enforces a strict Content Security Policy, the Install page lists the extra script-tag attributes to add. See [Demo Hubs](https://docs.supademo.com/share/multi-demo-sharing/demo-hub) for configuring the hub's content, categories, and appearance.

## Triggering in-app product tours using Google Tag Manager

You can also trigger Supademos and Showcases in-app without touching your codebase by using the Supademo script in conjunction with Google Tag Manager:

1. **Get the SDK**\
   Go to [Supademo Tour Setup](https://app.supademo.com/tour) and copy the client-side SDK script.
2. **Install the SDK via GTM**\
   In Google Tag Manager, create a new **Custom HTML** tag and paste the SDK script.
3. **Create a Tag to Fire Your Supademo**\
   Set up another **Custom HTML** tag using your unique Supademo API key and the ID of the Supademo you want to show.
4. **Choose a Trigger**\
   Decide when the Supademo should launch (e.g., on page load, button click, or image click). Configure this trigger in GTM.
5. **Save and Publish**\
   Save your changes, publish your GTM container, and test to confirm the Supademo fires as expected.

Please see the example below for a step-by-step walkthrough of how to set this up:

{% @supademo/embed url="<https://app.supademo.com/demo/cm96pjr6d47oheyp01cqnoyml>" demoId="cm96pjr6d47oheyp01cqnoyml" %}

## Frequently asked questions

### What plan do I need for in-app product tours?

In-app product tours via the Supademo SDK require a Scale, Growth or Enterprise plan. Placing a demo inline in your app with the standard iframe embed code works on every plan, including Free.

### Why isn't my in-app tour opening?

First, confirm the SDK script tag is present and that you initialize `Supademo("YOUR_API_KEY", ...)` after the DOM is rendered — in single-page apps, initialization must run after your framework mounts. Then open the browser console and look for a `Supademo error:` message, which names the cause:

* **"Could not find demo. Check embed code"** — the demo ID is wrong or the demo was deleted.
* **"Invalid workspace. Embedded demo is not in your workspace"** — the demo ID belongs to a different workspace than your API key.
* **"Workspace plan is invalid. Check your plan status"** — your plan does not include in-app tours.

For iframe-level issues, see [Embed not loading](https://docs.supademo.com/troubleshooting/embed-not-loading).

### Can I pass the logged-in user's name or email into a tour?

Yes. Pass `email`, `name`, and custom `variables` when initializing the SDK (for `data` attribute triggers) or in the `loadDemo()` / `loadShowcase()` call (for programmatic triggers). The values fill dynamic variables in your demo's text — see Variables in Embeds.

### How do I know when a user finishes a tour?

Listen for the `Supademo:completed` event with the Embed Events API. Embedded demos emit `postMessage` events for load, start, slide changes, progress, completion, and close, so your app can advance onboarding checklists or fire analytics when a tour ends.

### Do users need a Supademo account to view in-app tours?

No. Tours render inside your app for any user who can see the triggering element — viewers never need a Supademo account.
