> ## Documentation Index
> Fetch the complete documentation index at: https://novu-c5de82d9-nv-8794-quote-reply-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Web Chat

> Add the Web Chat channel, install @novu/react, and send a first message in your product UI.

Web Chat is how you embed an agent inside your own app. It is an [Agent Communication Infrastructure (ACI)](/agents/get-started/what-is-aci) channel, the same layer Slack and Teams use, except you own the surface: message list, composer, and layout.

The React client is [`useWebChat`](/platform/sdks/react/hooks/use-web-chat) from `@novu/react`. There is no prebuilt `<WebChat />` component. If you are not on React, use [`conversation()`](/platform/sdks/javascript#web-chat) from `@novu/js`.

## Setup

Create an agent and keep it **active**. Then add the channel in the dashboard:

1. Open the agent in the Novu dashboard.
2. Add **Web Chat**. Novu creates the `novu-web-chat` integration if it is missing.

## Install

Collect these values from the dashboard, then install `@novu/react`:

* Application identifier from [API Keys](https://dashboard.novu.co/api-keys)
* A [subscriber](/platform/additional-resources/glossary) id for the signed-in person
* The public agent identifier from the agent page

```package-install theme={null}
npm install @novu/react
```

<Note>
  `@novu/react` requires React 18 or later (`^18.0.0` or `^19.0.0`).
</Note>

Place `NovuProvider` above the chat. `useWebChat` gets the Novu client from that context.

<Tabs>
  <Tab title="US">
    ```tsx theme={null}
    import { NovuProvider } from '@novu/react';

    export function App() {
      return (
        <NovuProvider
          applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
          subscriber="YOUR_SUBSCRIBER_ID"
        >
          <Chat />
        </NovuProvider>
      );
    }
    ```
  </Tab>

  <Tab title="EU">
    ```tsx theme={null}
    import { NovuProvider } from '@novu/react';

    export function App() {
      return (
        <NovuProvider
          applicationIdentifier="YOUR_APPLICATION_IDENTIFIER"
          subscriber="YOUR_SUBSCRIBER_ID"
          apiUrl="https://eu.api.novu.co"
          socketUrl="wss://eu.socket.novu.co"
        >
          <Chat />
        </NovuProvider>
      );
    }
    ```
  </Tab>
</Tabs>

`NovuProvider` signs the subscriber in. `useWebChat` selects which agent to talk to.

<Note>
  Replace `YOUR_*` placeholders with values from [API Keys](https://dashboard.novu.co/api-keys) and [Subscribers](/platform/additional-resources/glossary).
</Note>

<Prompt description="Add Novu Web Chat to my React app" icon="plug" actions={["copy", "cursor"]}>
  # Add Novu Web Chat to a React app

  Install `@novu/react`. Wrap the app in `NovuProvider`. Call `useWebChat` and render your own message list and composer. There is no prebuilt `<WebChat />` component.

  Canonical example: [https://docs.novu.co/agents/channels/web-chat](https://docs.novu.co/agents/channels/web-chat)

  ALWAYS:

  * Detect the project's package manager and use it for installation
  * Use `NovuProvider` from `@novu/react` (not a second Novu client)
  * Pass the dashboard agent identifier as `agentId`
  * Disable the composer while `isRunning` or `isLoading` is true
  * Use TypeScript, no comments, no empty props

  NEVER:

  * Invent a `<WebChat />` component from `@novu/react`. It does not exist.
  * Use `useChat` from `@ai-sdk/react`. Web Chat uses `useWebChat`.
  * Compute HMAC hashes in the browser
  * Hardcode real API keys
</Prompt>

## Send a first message

Call `useWebChat` inside `NovuProvider`. Render text parts, then send with `sendMessage`.

```tsx theme={null}
const { messages, sendMessage, isRunning, isLoading, error } =
  useWebChat({
    agentId: 'YOUR_AGENT_IDENTIFIER',
  });
```

```tsx theme={null}
{error ? <p>{error.message}</p> : null}

<ul>
  {messages.map((message) => (
    <li key={message.id}>
      <strong>{message.role}</strong>{' '}
      {message.parts.map((part, index) =>
        part.type === 'text' ? (
          <span key={index}>{part.text}</span>
        ) : null
      )}
    </li>
  ))}
</ul>
```

```tsx theme={null}
<form
  onSubmit={(event) => {
    event.preventDefault();
    const form = event.currentTarget;
    const input = form.elements.namedItem('text') as HTMLInputElement;
    void sendMessage(input.value);
    form.reset();
  }}
>
  <input name="text" disabled={isRunning || isLoading} />
  <button type="submit" disabled={isRunning || isLoading}>
    Send
  </button>
</form>
```

Omit `conversationId` to start a new chat. The first successful send creates the conversation.

## What to read next

<Columns cols={2}>
  <Card href="/agents/channels/web-chat/messages" title="Messages" icon="message-square">
    Render message parts in the timeline.
  </Card>

  <Card href="/agents/channels/web-chat/tools" title="Tools" icon="wrench">
    Tool calls, approval, and MCP connect.
  </Card>

  <Card href="/agents/channels/web-chat/generative-ui" title="Generative UI" icon="sparkles">
    Custom data parts and structured UI.
  </Card>

  <Card href="/agents/channels/web-chat/conversations" title="Conversations" icon="messages-square">
    Resume chats, load history, and reconnect.
  </Card>

  <Card href="/agents/channels/web-chat/recipes/assistant-ui" title="assistant-ui" icon="layout">
    Build with the assistant-ui library.
  </Card>

  <Card href="/agents/channels/web-chat/security" title="Security" icon="shield">
    HMAC hashes before you ship to production.
  </Card>

  <Card href="/platform/sdks/react/hooks/use-web-chat" title="useWebChat" icon="code">
    Hook props, return value, and callbacks.
  </Card>

  <Card href="/platform/sdks/javascript#web-chat" title="JavaScript SDK" icon="code">
    Call `loadWebChat(novu)`, then `novu.webChat.conversation()` in `@novu/js`.
  </Card>
</Columns>
