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

# Widget v5 Companion mode

> Bring Companion into your website with Widget v5. Configure floating layouts, page context, marked screenshots, mentions and available AI features.

Companion brings help into the page your visitor is already using. Open it from a small launcher, ask a question, and move between a floating workspace, sidebar and fullscreen as the task grows.

<Frame>
  <video src="https://platform.open.cx/changelog/widget-v5-companion.mp4" controls muted playsInline aria-label="Widget v5 Companion: opening, streaming replies, page annotations and a scheduled follow-up" />
</Frame>

<Info>
  This guide uses **Widget v5 beta**. Install a v5 package first; the `latest`
  tag still installs v4. Companion is a display option, while streaming and AI
  capabilities depend on your organization's configuration.
</Info>

## Add Companion to your site

Get your widget token from [Channels → Web chat](https://platform.open.cx/channels/configure/widget). For a React integration:

```bash theme={"dark"}
npm install @opencx/widget-react@5.0.0-beta.0
```

Mount the widget once in your app's client-side layout:

```tsx theme={"dark"}
import { Widget } from "@opencx/widget-react";

export function SupportWidget() {
  return (
    <Widget
      options={{
        token: "<WIDGET_TOKEN>",
        displayMode: "companion",
        companion: {
          layouts: ["compact", "sidebar", "fullscreen"],
          defaultLayout: "compact",
        },
        context: () => ({
          page: {
            url: window.location.origin + window.location.pathname,
            title: document.title,
          },
        }),
      }}
    />
  );
}
```

For an HTML site, follow [Install Widget](/widget/install-widget) and pass the same options directly to `initOpenScript`. Use one integration on a page. If you set `inline: true`, inline rendering takes precedence over Companion mode.

<Tip>
  [Install the integration skill](/widget/agent-skills), then ask your coding
  assistant: “Use opencx-widget-integration to add Widget v5 beta in Companion
  mode to this app. Exclude query strings, fragments and private path or title data from page context.”
</Tip>

## Choose the layouts visitors can use

| Option       | What visitors see                                                |
| ------------ | ---------------------------------------------------------------- |
| `compact`    | A floating workspace. The layout picker calls this **Floating**. |
| `sidebar`    | A panel at the page edge. It floats over the page by default.    |
| `fullscreen` | An expanded workspace with more room for longer replies.         |

`companion.layouts` controls the choices and their order. Keep one layout to hide the picker. `defaultLayout` accepts `compact` or `sidebar`; when omitted, the first allowed layout is used. An empty layout list falls back to all three.

To place Companion beside your page instead of over it:

```tsx theme={"dark"}
<Widget
  options={{
    token: "<WIDGET_TOKEN>",
    displayMode: "companion",
    companion: {
      defaultLayout: "sidebar",
      layouts: ["sidebar", "fullscreen"],
      sidebar: { side: "auto", mode: "docked", width: 400 },
    },
  }}
/>
```

Docked mode reframes the host page to make space for the sidebar. Use `mode: 'floating'` when the page layout should stay unchanged. `side: 'auto'` uses the right edge on left-to-right pages and the left edge on right-to-left pages.

## Enable the capabilities you need

Open [Channels → Web chat](https://platform.open.cx/channels/configure/widget) to copy your widget token and manage website features next to a live preview. Feature switches save as you change them; a successful save refreshes the preview. On smaller screens, use the **Settings** and **Preview** tabs.

| Web chat setting             | What it enables                                                 |
| ---------------------------- | --------------------------------------------------------------- |
| **Rich replies**             | Cards, tables and forms in answers when streaming is available. |
| **Voice dictation**          | Speaking into the message composer.                             |
| **Sees the page**            | Page context, selected text, marked regions and mentions.       |
| **Acts on the page**         | Letting the agent point to and highlight page elements.         |
| **Asks to narrow a request** | Offering choices when a request needs clarification.            |

Use **Advanced settings** at the bottom of the page, or open [Settings → Advanced](https://platform.open.cx/settings/ai-features), for capabilities used across channels:

* **Progress updates** and **Remembers past sessions** control how the agent keeps customers informed and uses earlier sessions.
* **Scheduled follow-ups**, **Task plans**, **Workspace** and **Builds mini apps** are available on request. Enabled scheduled follow-ups let the agent check back and continue the same session later.
* Features available to your organization have a switch. Other features show **Contact sales** to request access. Editing requires the appropriate settings permission.

Manage transfer to your team separately in [Handoff settings](https://platform.open.cx/settings/handoff).

Streaming must also be enabled for your organization. Selecting Companion or installing v5 does not turn it on. If replies still arrive all at once, contact your OpenCX administrator or support team to check availability.

You can narrow supported features for one embed. For example, add `features: { dictation: false, clientTools: false }` to its options to hide dictation and prevent the agent from highlighting that page. Setting a feature to `true`, or omitting it, leaves the organization setting in charge. There is no per-embed `features.attachments` switch.

## Share the current page

Host-supplied context is sent with messages, stored in the session history, and can be included in the agent’s input. Send only the page information the agent needs. The examples combine `window.location.origin` and `window.location.pathname`, so query parameters and URL fragments are excluded. Those values can contain login tokens, search terms or other private data and should not become part of the stored session. If your path or page title also contains private information, replace it with an approved route label or omit it.

Use a `context` function so each message includes the page at the time it is sent. You can also provide the record the visitor is viewing:

```tsx theme={"dark"}
<Widget
  options={{
    token: "<WIDGET_TOKEN>",
    displayMode: "companion",
    context: () => ({
      page: {
        url: window.location.origin + window.location.pathname,
        title: document.title,
      },
      entity: {
        type: "order",
        id: "order_123",
        title: "Order #123",
        meta: { status: "processing" },
      },
    }),
  }}
/>
```

Replace the example entity with the current record from your application. It appears as a removable context pill in the composer when page context is enabled. URL changes refresh the pill. If the selected record changes without navigation, notify the widget:

```js theme={"dark"}
window.dispatchEvent(new Event("opencx:context-changed"));
```

In an app that updates without reloading, have the callback read current state from a store or ref. In beta.0, replacing `options.context` after initialization does not reliably update every sending path. Keep a callback that reads fresh values rather than reinitializing the widget on each navigation.

<Note>
  Only supply context you intend the agent to receive. `features.pageContext:
      false` disables widget-collected page context and its controls; it does not
  remove the host application's `context` from messages. Remove or narrow that
  callback separately when needed.
</Note>

## Mark a region and attach a screenshot

With **Sees the page** enabled:

1. Open the expanded Companion panel and choose **Mark something on the page to ask about it** in the composer.
2. Click the page element you want to discuss. Choose a shape such as **Box**, **Circle** or **Arrow**, and adjust the marked region.
3. Add a note such as “Explain this balance.” Press Enter or choose **Attach mark**.
4. Review the marked screenshot in the composer, add your question, and send. Remove the attachment first if you change your mind.

Press Escape to cancel marking. These controls appear in the expanded panel; set `companion.quickAskTools: 'all'` if you also want attachment and page-mark controls in the quick-ask bar.

## Let visitors mention records

Configure `mentions.items` for a fixed list, or `mentions.search` for records loaded as the visitor types. Each item needs `type`, `id` and `title`:

```tsx theme={"dark"}
<Widget
  options={{
    token: "<WIDGET_TOKEN>",
    displayMode: "companion",
    mentions: {
      items: [
        { type: "order", id: "order_123", title: "Order #123" },
        { type: "order", id: "order_124", title: "Order #124" },
      ],
    },
  }}
/>
```

Visitors type `@` and pick a record. The selected records travel with the message when page context is enabled. Supply only records the signed-in visitor is allowed to access; mentioning an ID does not grant access to it.

## Verify the experience

Open the launcher, switch layouts and send a message. With streaming enabled, confirm text arrives progressively and **Stop** interrupts the reply. A message sent during a reply can steer the current task or wait for it to finish.

Then navigate to a different page before sending, attach a marked screenshot, and reload to check session history. If scheduled follow-ups are enabled, ask for a check-in at a specific time and confirm the schedule the agent creates. Test human handoff as part of your normal support flow.

See the [configuration reference](/widget/configuration-reference#widget-v5-options) for more options and [Migrate to v5](/widget/migrate-to-v5) for existing integrations.
