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

# Embedding Devic in your product

> Two ways to put an assistant inside your product: a hosted widget you paste in, or React components you build with.

There are two ways to put a Devic assistant inside your product, and which one you want depends on whether you are writing React.

***

## Without code: the hosted widget

Every assistant has a **Chat Widget** section in its configuration: appearance, welcome message, suggested messages, file uploads, language and access — with a live preview beside it and a **Get Code** button that hands you the snippet to paste into your page.

![Widget configuration](https://mintcdn.com/devic/DKyKkxiOLW4okLYC/images/embed/widget-config.png?fit=max\&auto=format\&n=DKyKkxiOLW4okLYC\&q=85\&s=d6815a79cf3b4305027f7415a1ef1321)

Nothing to install and nothing to build. It is the right choice for a marketing site, a help centre, or anywhere the chat is a self-contained thing sitting on top of the page.

![The chat widget in a product](https://mintcdn.com/devic/DKyKkxiOLW4okLYC/images/embed/widget-live.png?fit=max\&auto=format\&n=DKyKkxiOLW4okLYC\&q=85\&s=89ffdc72a2582da44a9e262ee1813d39)

***

## With React: `@devicai/ui`

When the assistant needs to be *part of* your interface rather than sitting on it — reading the form the user is filling in, writing into a field, or looking like the rest of your product — use the library.

`@devicai/ui` is a React library that puts a Devic assistant inside your product: a chat drawer, a command bar, a generation button — connected to the public API, styled to your application.

```bash theme={null}
npm install @devicai/ui
```

```jsx theme={null}
import { DevicProvider, ChatDrawer } from '@devicai/ui';
import '@devicai/ui/styles.css';

export default function App() {
  return (
    <DevicProvider apiKey="devic-xxx">
      <ChatDrawer
        assistantId="support-assistant"
        options={{
          position: 'right',
          welcomeMessage: 'Hello! How can I help?',
          suggestedMessages: ['Where is my order?', 'I need an invoice'],
        }}
      />
    </DevicProvider>
  );
}
```

***

## What is in the box

> [card] ChatDrawer
>
> A complete chat panel: history, attachments, voice input, tool timeline, feedback.

> [card] AICommandBar
>
> A spotlight-style bar bound to a keyboard shortcut, with slash commands and history.

> [card] AIGenerationButton
>
> A button that generates into a field — directly, through a modal, or in a tooltip.

> [card] useDevicChat
>
> The hook underneath, for when you want your own interface entirely.

Plus `CoreMemoryModal` for [what the assistant remembers](https://docs.devic.ai/devic/memory/core-memory.md) and `IntegrationsModal` for [the apps each user connects](https://docs.devic.ai/devic/integrations/for-end-users.md).

***

## Authenticate properly

> [!WARNING]
>
> An `apiKey` prop puts that key in your bundle, where anyone can read it. That is acceptable while you are building and **not** acceptable in production for a multi-customer product: with the key alone, someone can claim to be any of your tenants.
>
> Use [tenant sessions](https://docs.devic.ai/devic/multi-tenant/tenant-sessions.md) instead. The provider takes a function that fetches a session from *your* backend and renews it on its own — and the page then carries no key at all.

```jsx theme={null}
<DevicProvider
  getTenantSession={async () => {
    const r = await fetch('/api/devic-session', { credentials: 'include' });
    return r.json();
  }}
  onSessionExpired={() => location.assign('/login')}
>
  <App />
</DevicProvider>
```

If you restrict the key that ships in the browser, Devic offers a ready-made scope for exactly this case — see [API keys](https://docs.devic.ai/devic/administration/api-keys.md).

***

## Client-side tools

Some things only the browser knows: where the user is, what is selected on screen, what is in the form they are filling in. The **Model Interface Protocol** lets the assistant call a function *in your page* as if it were any other tool.

```jsx theme={null}
const locationTool = {
  toolName: 'get_user_location',
  schema: {
    type: 'function',
    function: {
      name: 'get_user_location',
      description: 'Get the user current geographic location',
      parameters: { type: 'object', properties: {} },
    },
  },
  callback: async () => {
    const pos = await new Promise((ok, err) =>
      navigator.geolocation.getCurrentPosition(ok, err),
    );
    return { latitude: pos.coords.latitude, longitude: pos.coords.longitude };
  },
};

<ChatDrawer assistantId="support-assistant" modelInterfaceTools={[locationTool]} />
```

The assistant asks, your page answers, the conversation carries on. Nothing about the user's browser has to reach your server first.

***

## Making it look like yours

Every component is themed with CSS variables, so it inherits your product rather than announcing itself:

```css theme={null}
.devic-chat-drawer {
  --devic-primary: #4764e6;
  --devic-bg: #ffffff;
  --devic-text: #1a1a1a;
  --devic-radius: 12px;
}
```

For a single accent colour, `options={{ color: '#4764e6' }}` is enough.

***

## Next steps

> [card] [Configuring the chat drawer](https://docs.devic.ai/devic/embed/chat-widget.md)
>
> Options, callbacks, memory and connected apps.

> [card] [Tenant sessions](https://docs.devic.ai/devic/multi-tenant/tenant-sessions.md)
>
> Proving which user is calling.

> [card] [API reference](https://docs.devic.ai/api-reference/introduction.md)
>
> Everything the components call, callable yourself.

> [card] [CLI](https://docs.devic.ai/devic/cli/index.md)
>
> The same API from a terminal.


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