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

# Website Widget

> Embed a Duckie chat widget on your website

Add an AI-powered chat widget directly to your website for instant customer support. To deploy the widget for support agents without embedding code on a site, see [Chrome Extension](/integrations/messaging/widget-chrome-extension).

## Capabilities

| Capability             | Supported            |
| ---------------------- | -------------------- |
| **Knowledge Source**   | ✗                    |
| **Deployment Trigger** | ✓ Chat conversations |
| **Tool Actions**       | ✓ Send messages      |

## Setup

### Step 1: Create a Widget Deployment

1. Go to **Deploy**
2. Click **Create Deployment**
3. Select your agent
4. Choose **Website Widget** as the trigger
5. Configure appearance and behavior
6. Click **Create**

### Step 2: Get the Embed Code

After creating the deployment:

1. Click on the deployment to open settings
2. Go to the **Widget** tab
3. Copy the embed code

### Step 3: Add to Your Website

Add the embed code before the closing `</body>` tag:

```html theme={null}
<script>
(function(d,w){
  w.DuckieWidget={key:"wgt_cTqeFN4LNFCZORc3"};
  var s=d.createElement('script');
  s.src='https://app.useduckie.ai/widget/embed.js';
  s.async=true;
  d.head.appendChild(s);
})(document,window);
</script>
```

Replace `YOUR_DEPLOYMENT_ID` with your actual deployment ID.

## Customization

### Appearance

Customize the widget to match your brand:

| Option               | Description                        |
| -------------------- | ---------------------------------- |
| **Primary color**    | Button and header color            |
| **Position**         | Bottom-right or bottom-left        |
| **Welcome message**  | Initial greeting shown to visitors |
| **Placeholder text** | Input field placeholder            |

### Behavior

Configure how the widget behaves:

| Option             | Description                        |
| ------------------ | ---------------------------------- |
| **Auto-open**      | Open automatically after X seconds |
| **Show on pages**  | Specific pages or all pages        |
| **Business hours** | Only show during certain hours     |
| **Require email**  | Ask for email before starting chat |

## Advanced Configuration

### JavaScript API

Control the widget programmatically:

```javascript theme={null}
// Open the widget
DuckieWidget('open');

// Close the widget
DuckieWidget('close');

// Send a message
DuckieWidget('sendMessage', 'Hello!');

// Set user information
DuckieWidget('identify', {
  email: 'user@example.com',
  name: 'John Doe',
  customFields: {
    plan: 'premium',
    accountId: '12345'
  }
});
```

### Passing Context

Pass contextual information to help the agent:

```javascript theme={null}
DuckieWidget('setContext', {
  currentPage: window.location.pathname,
  product: 'Enterprise Plan',
  userId: '12345'
});
```

## Proactive messages

Normally the visitor starts the conversation. With proactive messages your own
page code starts it instead — the agent opens with a greeting before the visitor
types anything. Use it to offer help on a pricing page, nudge a visitor who has
stalled in checkout, or react to an in-app event.

Call `window.DuckieWidget.trigger(...)` from your site:

```javascript theme={null}
// Show a fixed opener and reveal a teaser on the launcher.
window.DuckieWidget.trigger({
  message: "Comparing plans? I can help you pick the right one.",
});
```

### Choosing who writes the opener

| Mode                | Pass                            | What happens                                                                                                                                             |
| ------------------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Fixed message**   | `message`                       | Your exact text appears as the agent's first message right away. The agent stays quiet until the visitor replies, so nudges nobody answers cost nothing. |
| **Agent-generated** | `instructions` (omit `message`) | The agent writes the opener itself, using your `instructions` as private context for why the conversation started.                                       |

```javascript theme={null}
// Let the agent write the opener, given context about why it fired.
window.DuckieWidget.trigger({
  instructions: "Visitor has been on the Enterprise pricing page for 60s.",
  metadata: { plan: "enterprise", page: "/pricing" },
});
```

### Options

`trigger(options)` accepts:

| Option         | Type   | Description                                                                                                                                                            |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `message`      | string | Verbatim opener shown as the agent's first message. Selects fixed-message mode. Max 4000 characters.                                                                   |
| `instructions` | string | Private context passed to the agent about why the conversation started, used when `message` is omitted. Never shown to the visitor. Max 4000 characters.               |
| `metadata`     | object | Extra string key/value context attached to the conversation for the agent. Combined with the page metadata the widget already collects. Non-string values are ignored. |
| `display`      | string | `"open"` opens the widget immediately. Omit it (the default) to show a small teaser on the launcher that opens the conversation when clicked.                          |

`trigger()` returns a Promise that resolves with the result, including `runId`
and `status`:

| `status`     | Meaning                                                                                               |
| ------------ | ----------------------------------------------------------------------------------------------------- |
| `created`    | A new conversation was started.                                                                       |
| `suppressed` | The visitor already has a conversation in progress, so the trigger was skipped to avoid interrupting. |

### Triggering before the script loads

If you might call `trigger()` before `embed.js` has finished loading, push the
call onto a queue instead — it runs as soon as the widget is ready:

```javascript theme={null}
window.DuckieWidget = window.DuckieWidget || { key: "wgt_..." };
(window.DuckieWidget.q = window.DuckieWidget.q || []).push([
  { message: "Need a hand getting set up?" },
]);
```

<Info>
  Proactive triggers are rate-limited per visitor and use the same agent and
  origin rules as normal widget chat. A trigger from an origin without an active
  widget deployment, or for an inactive agent, is rejected.
</Info>

## Best Practices

### Strategic Placement

* Show on pages where users need help (pricing, checkout, docs)
* Consider hiding on landing pages to reduce distraction
* Use page-specific welcome messages

### Provide Context

Pass user and page context so the agent can personalize responses:

* User's plan or tier
* Current page or product
* Account information

### Set Expectations

Use the welcome message to set expectations:

* "Hi! I'm an AI assistant. How can I help?"
* Mention response times for complex issues

## Example Implementations

### Documentation Site

```javascript theme={null}
DuckieWidget('init', {
  deploymentId: 'YOUR_ID',
  welcomeMessage: 'Need help with our docs? Ask me anything!',
  position: 'bottom-right'
});

// Pass current doc page
DuckieWidget('setContext', {
  currentDoc: document.title
});
```

### SaaS Dashboard

```javascript theme={null}
DuckieWidget('init', {
  deploymentId: 'YOUR_ID',
  welcomeMessage: 'Hi {{user.name}}! How can I help?'
});

// Identify the user
DuckieWidget('identify', {
  email: currentUser.email,
  name: currentUser.name,
  plan: currentUser.subscription.plan
});
```

## Troubleshooting

### Widget not appearing

* Check browser console for JavaScript errors
* Verify the deployment ID is correct
* Ensure the script is loading (check Network tab)

### Slow to load

* The widget script is loaded asynchronously
* Initial load may take 1-2 seconds
* Subsequent loads are cached

### Styling conflicts

* Widget uses Shadow DOM to isolate styles
* If issues persist, check for global CSS resets
