> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tavus.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Embed

> Render a Tavus conversation inline in your layout with the tavus-embed custom element - in plain HTML, React, or Next.js.

## Overview

`<tavus-embed>` renders a Tavus conversation inline, inside your own layout. It uses the same managed deployment flow as the [widget](/sections/deployments/widget), but instead of a floating launcher the experience lives where you put the element - a product page, a demo section, a dashboard panel.

The embed renders in a shadow DOM and adapts to its container: it maintains a `16:9` aspect ratio in wide containers and switches to a compact `9:16` portrait layout in narrow ones.

PALs with a [Magic Canvas](/sections/conversational-video-interface/magic-canvas/overview) skill render cards in the embed automatically. See [Hosted embed & widget](/sections/conversational-video-interface/magic-canvas/integrations/hosted) for Canvas-specific behavior.

## Installation

<Tabs>
  <Tab title="CDN (static pages)">
    ```html theme={null}
    <div style="width: 720px; aspect-ratio: 16 / 9;">
      <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID"></tavus-embed>
    </div>
    <script src="https://unpkg.com/@tavus/embed"></script>
    ```

    To pin an exact version instead of tracking the latest beta, use a versioned URL such as `https://unpkg.com/@tavus/embed@0.1.0`.
  </Tab>

  <Tab title="React">
    ```bash theme={null}
    npm install @tavus/embed@latest
    ```

    Importing the package registers the `<tavus-embed>` custom element as a side effect. Use the tag directly in JSX:

    ```tsx theme={null}
    import "@tavus/embed";

    export function Support() {
      return (
        <div style={{ width: "100%", maxWidth: 960, aspectRatio: "16 / 9" }}>
          <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID" />
        </div>
      );
    }
    ```
  </Tab>

  <Tab title="Next.js">
    ```bash theme={null}
    npm install @tavus/embed@latest
    ```

    The element touches browser APIs at registration time, so import it in a client component:

    ```tsx theme={null}
    "use client";

    import "@tavus/embed";

    export function TavusEmbed() {
      return (
        <div style={{ width: "100%", maxWidth: 960, aspectRatio: "16 / 9" }}>
          <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID" />
        </div>
      );
    }
    ```
  </Tab>
</Tabs>

## Attributes

| Attribute | Type | Description |
| - | - | - |
| `deployment-id` | string | The Tavus deployment ID. Fetches configuration from `/v2/deployments/:id/init`. |
| `conversational-context` | string | Extra context injected into the conversation at start (maps to `conversational_context`). Use it to pass what the deployment should know about the current user or page. |
| `custom-greeting` | string | Overrides the PAL's opening line for this conversation (maps to `custom_greeting`). If omitted, the PAL's `greeting` or `dynamic_greeting` applies. |
| `memory-stores` | string | Comma-separated memory tags (maps to `memory_stores`). Optional — automatic per-visitor memory is on by default. Pass a stable per-user identifier when you want memory to follow a specific user instead. |
| `expand-options` | JSON string | Lifts the embed out of the page into a modal overlay for the conversation. See [Expanded overlay](#expanded-overlay). |

## Context and greeting

`conversational-context` and `custom-greeting` let you tailor a single conversation at start time:

```html theme={null}
<div style="width: 720px; aspect-ratio: 16 / 9;">
  <tavus-embed
    deployment-id="YOUR_DEPLOYMENT_ID"
    conversational-context="The user is Jane, on the Pro plan, viewing the billing page."
    custom-greeting="Hey Jane, welcome back - want to pick up where we left off?"
  ></tavus-embed>
</div>
<script src="https://unpkg.com/@tavus/embed"></script>
```

`conversational-context` overrides the deployment's configured default context for this conversation; when omitted, the deployment default is used. `custom-greeting` sets the PAL's opening line. If you omit it, the PAL's `greeting` or `dynamic_greeting` applies. Empty or whitespace-only values are ignored, so an empty attribute behaves the same as not setting it.

## Persistent memory

`memory-stores` lets a returning user pick up where they left off. A tag is a memory namespace: every conversation that uses the same tag shares one bucket of memories, so the PAL can remember that user across sessions and devices.

Tags are global to your account, **not** scoped to a deployment. A bare `user-12345` would share the same memory across every deployment that uses it. To keep memory specific to one deployment, combine the deployment ID with your user ID:

```html theme={null}
<div style="width: 720px; aspect-ratio: 16 / 9;">
  <tavus-embed
    deployment-id="YOUR_DEPLOYMENT_ID"
    memory-stores="YOUR_DEPLOYMENT_ID-user-12345"
  ></tavus-embed>
</div>
<script src="https://unpkg.com/@tavus/embed"></script>
```

Pass multiple stores as a comma-separated list (`memory-stores="YOUR_DEPLOYMENT_ID-user-12345,team-acme"`). Empty or whitespace-only values are ignored.

<Note>
  In the [PAL Maker](https://maker.tavus.io/dev), open your deployment's **Settings** and use **Unique memory per visitor** (maps to `customization.conversation.unique_memory_tag`; on by default). When that toggle is on and you omit `memory-stores`, the widget or embed generates an anonymous per-browser ID (stored in `localStorage`, scoped to that deployment) and sends it as `memory_stores` on each conversation start. Memory persists for that visitor in the same browser, but not across devices or after storage is cleared. Set `memory-stores` to your own stable user ID when you want memory to follow a logged-in user everywhere. With the toggle off and no `memory-stores` attribute, no memory store is sent.
</Note>

## Sizing

`<tavus-embed>` fills its parent: the host element is `width: 100%; height: 100%; max-height: 100vh; overflow: hidden`. Give it a parent with a definite size, or wrap it in a container with `aspect-ratio`:

```html theme={null}
<div style="width: 720px; aspect-ratio: 16 / 9;">
  <tavus-embed deployment-id="YOUR_DEPLOYMENT_ID"></tavus-embed>
</div>
```

<Warning>
  If the parent has no resolved height - for example a chain of auto-height flex containers - the embed cannot size itself. Give the parent an explicit height or an `aspect-ratio`, or ensure the full chain (`html`, `body`, root element, container) resolves to a real height.
</Warning>

## Expanded overlay

`expand-options` lifts the embed out of your layout into a modal overlay for the conversation, so a small inline card can become a full call without you building a modal. The card returns to the page when the call ends.

```html theme={null}
<div style="width: 360px; aspect-ratio: 16 / 9;">
  <tavus-embed
    deployment-id="YOUR_DEPLOYMENT_ID"
    expand-options='{"enabled": true}'
  ></tavus-embed>
</div>
<script src="https://unpkg.com/@tavus/embed"></script>
```

| Key | Type | Description |
| - | - | - |
| `enabled` | boolean | Expand the embed for the conversation. Default `false`. |
| `aspect` | `"horizontal"` \| `"vertical"` | `16:9` or `9:16`. Default `"horizontal"`. |
| `custom_aspect` | string \| number | Any ratio, written as `"4:3"`, `"16/9"`, or a number (width ÷ height). Overrides `aspect`. |
| `max_width` | number (px) | Largest width the expanded card takes. A landscape card defaults to `1280`. |
| `max_height` | number (px) | Largest height the expanded card takes. A portrait card defaults to `900`. |
| `fullscreen` | boolean | Fill the viewport edge to edge. Default `false`. |

## Interacting from the page

The embed emits lifecycle events (`tavus:conversation-started`, `tavus:tool-call`, …) and exposes an imperative API for starting, ending, and messaging the conversation. See [Host communication](/sections/deployments/host-communication) for the full reference.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.