<!-- AvatarFactory Docs · https://avatarfactory.in/docs/integrations/website-embed · Full map: https://avatarfactory.in/llms.txt -->

# Website embed

Put a live talking avatar on any website with one script tag. No React, no npm, no backend — WordPress, Webflow, Wix, Squarespace or plain HTML.

The script-tag embed adds the floating avatar widget to any page. It loads the avatar
in a sandboxed frame served by AvatarFactory, so it cannot clash with your site's code
or styles, and your page talks to it through a small JavaScript API.

## Before you start

The embed runs on a **deployment**: a public, domain-locked credential for one avatar,
with its own minute budget.

| Requirement | Where |
| --- | --- |
| A published avatar | Platform → your avatar → Publish. See Avatars. |
| A paid plan | Deployments are not available on the free plan. |
| A deployment | Platform → open the avatar → Deploy → Website → Script tag → New deployment. |
| Your domain on the deployment | Add every domain the widget runs on, e.g. example.com and www.example.com. |

> You do **not** need an API key. A deployment ID (`dep_…`) is public: it only works on
>   the domains you authorize, and it never spends more than the budget you set on it.

## Install

### Step 1 — Copy the snippet

The Deploy tab shows it with your deployment ID filled in:

```html
<script async src="https://widget.avatarfactory.in/v1/embed.js" data-deploy-id="dep_YOUR_DEPLOYMENT_ID"></script>
```

### Step 2 — Paste it before the closing body tag

Add it to every page that should show the avatar, usually through your site's global
footer or custom-code setting:

- **WordPress:** a header/footer code plugin, or your theme's `footer.php`.
- **Webflow:** Site settings → Custom code → Footer code.
- **Wix / Squarespace:** the site-wide custom code or code injection setting (footer).

### Step 3 — Publish and open your site

The launcher appears in the corner set on the deployment. Click it to start a call. The
browser asks for the microphone the first time.

## Control it from your page

The snippet defines `window.avatarfactory`. Call it after the script has loaded, or
queue commands before it loads — they run in order once it does:

```html
<script>
  window.avatarfactory = window.avatarfactory || [];
  window.avatarfactory.push(["context", { page: "pricing", plan: "Pro" }]);
</script>
<script async src="https://widget.avatarfactory.in/v1/embed.js" data-deploy-id="dep_YOUR_DEPLOYMENT_ID"></script>
```

Once loaded, every command is also a method: `window.avatarfactory.open()`.

| Command | What it does |
| --- | --- |
| context(snapshot) | Tells the avatar what the user is looking at — any object or string. Each call replaces the last; rapid calls are batched, and only the final snapshot in a 500ms burst is sent. |
| event(name, detail?) | Reports something that happened, e.g. event('cart.updated', { items: 3 }). It is added to what the avatar knows, without replacing the context. |
| open() / close() | Expands or collapses the widget panel. |
| start() / stop() | Starts or ends the call. Browsers only allow audio after a user gesture, so prefer letting the user press the call button. |
| action(definition) | Registers an action the avatar can run on your page, such as adding to cart. Same definition as the SDK's actions. |
| on(name, listener) / off(name, listener) | Listens for widget events (below). |
| destroy() | Removes the widget and ends any call. |

### Events

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `ready` | `event` | — | The widget has loaded and is accepting commands. |
| `state` | `"dormant" \| "expanding" \| "expanded" \| "connecting" \| "live" \| "ended"` | — | The widget's stage changed. The listener receives the new stage. |
| `start` | `event` | — | A call started. |
| `stop` | `event` | — | A call ended. |
| `notice` | `{ kind, action? }` | — | The avatar spoke a notice instead of a conversation, e.g. minutes used up or the microphone blocked. |
| `error` | `{ code, fatal }` | — | An error. Codes match the SDK's error table. |
| `action.flow` | `ActionFlow` | — | Progress of an action the avatar is running. |

```js
window.avatarfactory.on("state", (stage) => {
  if (stage === "live") analytics.track("avatar_call_started");
});
```

## Content Security Policy

If your site sends a `Content-Security-Policy` header, allow the loader and the frame:

```text
script-src  https://widget.avatarfactory.in;
frame-src   https://widget.avatarfactory.in;
```

A blocked loader logs `[avatarfactory] blocked by this page's Content-Security-Policy`
in the browser console.

## Microphone and pages that block it

The widget's frame is granted the microphone, camera, screen capture and autoplay. A
page that itself refuses the microphone, such as a site builder's editor preview, cannot
pass it on. There the avatar says it cannot hear the user and suggests opening the page
in its own tab. The live site works normally.

## Troubleshooting

| What you see | What to do |
| --- | --- |
| Nothing appears | Check the console. “embed.js needs a data-deploy-id attribute” means the attribute is missing. A blocked request means a CSP rule (above). |
| Works on one domain, not another | Add the missing domain (including www. and any staging domain) to the deployment. |
| The widget appears but will not connect | The deployment may be paused, out of budget, or the plan's minutes may be used up. Check the Deploy tab. |

Building in React? Use the [AvatarWidget](/docs/sdk/react/widget) component instead —
same widget, rendered in your own app.
