---
id: website-embedding
title: Website Embedding
---

---

Integrating a chatbot to a website is relatively straightforward. As long as your chatbot is hosted on a physical or virtual server and is accessible via a URL, you can connect and integrate it to a website. Add the following script tag to the end of your `index.html` (or the default webpage, whichever it's named).

:::tip
Don't forget to replace `<your-url-here>` with the URL of your bot!
:::

```html
<script src="<your-url-here>/assets/modules/channel-web/inject.js"></script>
```

After the import script above, you need to locate and use the chatbot by initializing it to the `window` object:

```html
<script>
  window.botpressWebChat.init({
    host: "<your-url-here>",
    botId: "<your-bot-id>",
  })
</script>
```

That's it! Once you add these changes and save them to your website, the bot will become available, and its button will appear on your site the next time you browse it.

There is an example in the default botpress installation at [http://localhost:3000/assets/modules/channel-web/examples/embedded-webchat.html](http://localhost:3000/assets/modules/channel-web/examples/embedded-webchat.html)

:::info
If your botpress instance and your webchat instance is not on the same domain. You need to add a header to your botpress instance. You can check the [content-security-policy](https://content-security-policy.com/frame-ancestors/) documentation to enable a cross-origin for the injector.

- Nginx [example](https://content-security-policy.com/examples/nginx/)

:::

**Additional Option:**

| Property | Description                                                              |
| -------- | ------------------------------------------------------------------------ |
| `ref`    | The trusted reference of the user origin (generated by [security sdk][]) |

## Bot Information Page

The information page displays information like the website URL, a phone number, an e-mail contact address, and links to terms of services and privacy policies. You can also include a cover picture and an avatar for your bot.

How to set up the information page:

1. In the Admin, click the **Config** button next to the name of the bot you want to change.
2. Edit your bot information in the **More details** and **Pictures** sections.
3. Edit the file `data/global/config/channel-web.json` and set `showBotInfoPage` to `true`.
4. Refresh your browser.

You will see the page when starting a new conversation. The page is always accessible by clicking on the information icon in the top right corner of the chat window.

:::info
We edited the `global` configuration file for the sake of simplicity. To enable the bot information page on a single bot, visit that bot's studio UI and select **Config** (the last icon on the left-side menu with a cog).
:::

## Events Available

You can trigger events by calling the `window.botpressWebChat.sendEvent()` function. Below are some of them:

| name            | Description                                                       |
| --------------- | ----------------------------------------------------------------- |
| `show`          | This event opens the webchat                                      |
| `hide`          | This event closes the webchat                                     |
| `toggle`        | This event open or close the webchat depends on its current state |
| `message`       | This event sends a message (see example above)                    |
| `toggleBotInfo` | This event switches between bot infos and conversation page       |

### Show

The following function shows the chat window when you click the `show-bp` element.

```js
document.getElementById("show-bp").addEventListener("click", function () {
  window.botpressWebChat.sendEvent({ type: "show" })
})
```

### Hide

The following function hides the chat window when you click the `hide-bp` element.

```js
document.getElementById("hide-bp").addEventListener("click", function () {
  window.botpressWebChat.sendEvent({ type: "hide" })
})
```

### Changing Website Button

Most developers change the default webchat button which comes pre-packed in Botpress. This is the button that appears on your website (in the bottom right corner) when you integrate your chatbot in your website. This common styling change is usually applied to adopt a button which fits into the website theme. If you would like to change the default Botpress button, pass the `hideWidget` key to your `init` function. By doing so, the default chat button will not show up on your website.

```html
<script>
  window.botpressWebChat.init({
    host: "<your-url-here>",
    botId: "<your-bot-id>",
    hideWidget: true,
  })
</script>
```

You can then add a `click` event listener to any element on your web page (in most cases this entails creating a new button). Below is a code sample showing how to add event listeners to your custom elements.

```html
<script>
  document.getElementById("show-bp").addEventListener("click", () => {
    window.botpressWebChat.sendEvent({ type: "show" })
    window.botpressWebChat.sendEvent({ type: "message", text: "Hello!" })
  })
  document.getElementById("hide-bp").addEventListener("click", () => {
    window.botpressWebChat.sendEvent({ type: "hide" })
  })
</script>
```

### Toggle

The following function includes a ternary operator that toggles the chat to either be hidden or shown when you click the `toggle-bp` element.

```js
document.getElementById("toggle-bp").addEventListener("click", function () {
  window.botpressWebChat.sendEvent({ type: webchatOpen ? "hide" : "show" })
})
```

### Message

The following function lets you programmatically send a message to the user when you click the `send-message-bp` element.

```js
document
  .getElementById("send-message-bp")
  .addEventListener("click", function () {
    window.botpressWebChat.sendEvent({ type: "message", text: "Hello!" })
  })
```

## Runtime Configurations

The method `window.botpressWebChat.configure` allows you to change the chat's configuration during a conversation without having to reload the page.

The example below shows how you can change the chatbot's language to French when you click `change-lang-bp` on your website.

```js
document
  .getElementById("change-lang-bp")
  .addEventListener("click", function () {
    lastConfig.locale = "fr"
    window.botpressWebChat.configure(lastConfig)
  })
```

### Configuring a Custom User ID

Setting a value for `userId` in the webchat configuration allows you to store a custom id that can then be retrieved in actions and hooks.

```js
lastConfig.userId = "7021eccd-6c4b-4f05-9cb5-f881c95b1781" // can be any string but make sure it is unique
window.botpressWebChat.configure(lastConfig)
```

To retrieve the value, you simply have to access the property `webchatCustomId` in the user's attributes.

The example below shows how you can access the custom user ID inside an action or hook.

```js
//...

if (event.state.user.webchatCustomId) {
  const customUserId = event.state.user.webchatCustomId

  // make an API or database call using the id
  //...
}
```

### Sending Custom Payloads

All messages sent to a user consist of a `payload`. That payload has a `type` property that tells the webchat how the payload should render on the screen.

There are different ways to send that payload to the user:

- Sending a content element via the Flow Editor [example here](https://github.com/botpress/botpress/blob/master/modules/builtin/src/content-types/image.js);
- Sending an event via [hooks or actions](https://github.com/botpress/botpress/blob/master/examples/custom-component/src/hooks/after_incoming_middleware/sendoptions.js).

There are multiple types already built-in in Botpress (these are listed at the bottom of this page), but you can create them easily if you require more advanced components.

### Prevent Storing Sensitive Information

By default, the complete payload is stored in the database, so the information is not lost when the user refreshes the page. However, we may want to hide some properties deemed sensitive (such as password, credit card, etc.).

To remove this information, there is a special property that you need to set: `sensitive`. Here's an example:

```js
const payload = {
  type: "login_prompt",
  username: "someuser",
  password: "abc123",
  sensitive: ["password"],
}

// This is the information that will be persisted: { type: 'login_prompt', username: 'someuser' }
```

### Changing Avatar for Messages

If you need to display a different bot's avatar for some of the messages (like imitating changing author), you can achieve that by setting `botAvatarUrl` like this:

```js
const payload = {
  type: 'text',
  botAvatarUrl: 'http://some.url'
  text: 'Lorem ipsum'
}
```

## Creating a Custom Component

We already have an [example module](https://github.com/botpress/botpress/tree/master/examples/custom-component) showing how to create them. We will make a quick recap here. The debugger is implemented entirely as a custom component in the [extensions module](https://github.com/botpress/botpress/tree/master/modules/extensions/src/views/lite/components/debugger), so don't hesitate to take a look at how it was implemented there.

Custom components leverage the `custom` payload type, which allows you to inject any valid React component exported from a custom module.

1. Create a module (we have [example templates here](https://github.com/botpress/botpress/tree/master/examples/module-templates)).
2. Develop your component.
3. Export your component in the `lite.jsx` file ([here's a couple of different ways to do it](https://github.com/botpress/botpress/blob/master/examples/custom-component/src/views/lite/index.jsx)).
4. Send a custom payload to the user:

```js
payload: {
  type: "custom" // Important, this is how the magic operates
  module: "myModule" // The name of your module, must match the one in package.json
  component: "YourComponent" // This is the name of the component, exported from lite.jsx
  // Feel free to add any other properties here, they will all be passed down to your component
  myCustomProp1: "somemorestuff"
  someOtherProperty: "anything"
}
```

### Component Properties

A couple of properties are passed down to your custom component. These can be used to customize the displayed information and/or to pursue interactions.

| Property          | Description                                                                  |
| ----------------- | ---------------------------------------------------------------------------- |
| `...props`        | The payload properties are available on the root object (`this.props.`)      |
| `onSendData`      | This method can be used to send a payload to the bot on behalf of the user   |
| `onFileUpload`    | Instead of sending an event, this will upload the specified file             |
| `sentOn`          | This is the timestamp of the message.                                        |
| `isLastGroup`     | Indicates if your component is part of the group of messages sent by the bot |
| `isLastOfGroup`   | Indicates if your component is the last message in its group                 |
| `keyboard`        | This object allows you to manipulate the keyboard (more below)               |
| `wrapped`         | Represent any child components (more below)                                  |
| `incomingEventId` | The ID of the incoming event which was processed                             |
| `store`           | Grants access to the MOBX store of Channel Web (more on that below)          |

:::note
`isLastGroup` and `isLastOfGroup` can be combined to let your component know if the current message is the last one the user is seeing. This can be used, for example, to display feedback buttons, a login form, or anything else, that will disappear when the user continues the discussion.
:::

### The Store

The store orchestrates everything happening on the webchat: whether those buttons are displayed, which page is currently displayed, how to handle configuration changes, etc. This means that your component has a lot of flexibility. Here's a sample of the methods that you can use ([click here to see all of them](https://github.com/botpress/botpress/tree/master/modules/channel-web/src/views/lite/store)):

- Hide or show the chat
- Add or remove header buttons
- Change the size of the chat window
- Send messages or payloads
- Create a new conversation
- Update any configuration option
- Set a wrapper that will wrap every single message (more on that below)

Anything you can do while clicking on the UI can be done by your component.

### Injecting Your Components

Some components can be replaced by your own. There are also some placeholders that don't have any components, but you can inject yours. When you inject a component, it will receive the original component, so you can wrap it or change it completely. If there's a problem with your component, it will be replaced by the original one.

| Location             | Description                                                        |
| -------------------- | ------------------------------------------------------------------ |
| `below_conversation` | This component would be displayed just below the composer          |
| `before_container`   | This is displayed before the chat container (the debugger uses it) |
| `composer`           | This allows you to replace the zone where the user is typing       |

How to configure them:

```js
window.botpressWebChat.init({
...
  overrides: {
    before_container: [
      {
        module: 'extensions',
        component: 'Debugger'
      }
    ]
  }
})
```

### Wrappers

Wrappers allow you to transform a payload's content before passing it down to the renderer or another component. We have some [example components here](https://github.com/botpress/botpress/tree/master/examples/custom-component/src/views/lite/components/Advanced.jsx).

Here's an example of a wrapped text message:

```js
payload: {
  type: 'custom',
  module: 'myModule',
  component: 'MyComponent'
  wrapped: {
    type: 'text'
    text: 'Hello user!'
  }
}
```

It is also possible to chain multiple custom components using the `wrapped` property.

### Keyboards

The keyboard allows you to add elements before or after the composer. Keyboard items can be buttons or any other type of valid component. Use `Keyboard.Prepend` to display it before the composer, and `Keyboard.Append` to display it after.

```js
...
render(){
  // First of all, import the keyboard object
  const Keyboard = this.props.keyboard

  // Create any type of component
  const something = <div>This will be displayed over the composer, as long as visible is true</div>

  // Your custom keyboard will only be displayed if that message is the last one displayed
  const visible = this.props.isLastGroup && this.props.isLastOfGroup

  return (
    <Keyboard.Prepend keyboard={something} visible={visible}>
      This text will be displayed in the chat window
    </Keyboard.Prepend>à
  )
}
```

### Using a Button Keyboard

There is a built-in hook that makes it easy to add buttons to any element. You can pass down an array of buttons or an array of array of buttons.

```js
const payload = {
  type: 'text'
  text: 'hello',
  quick_replies: [
      [{ label: 'row 1, button 1', payload: 'something' }, { label: 'row 1, button 2', payload: 'something' }],
      [{ label: 'row 2, button 1', payload: 'something' }],
      [{ label: 'row 3, button 1', payload: 'something' }]
    ]
}
```

[security sdk]: https://botpress.com/reference/modules/_botpress_sdk_.security.html#getmessagesignature

## Acting Proactively

You may wish to make your bot act proactively on your website in response to some action, such as making the bot speak first, suggesting they buy the product, or asking them for feedback on services they were using.

### Send an Event From the Webpage

First you need to open the webchat (either manually or programmatically) and then send an event from the webpage.

```js
window.botpressWebChat.sendEvent({
  type: "proactive-trigger",
  channel: "web",
  payload: {
    text: "fake message",
  },
})
```

The property `type: 'proactive-trigger'` is used to identify the event so we can catch it and act on it later on.

### Catch the Event in a Hook

This event will be dispatched to the bot so you need to add a handler for it. If this event is not handled, it will be interpreted as a user message.

This snippet should be added to the `before_incoming_middleware` hook:

```js
// Catch the event sent from the webpage
if (event.type === "proactive-trigger") {
  // You custom code
}
```

:::tip
Use `event.setFlag(bp.IO.WellKnownFlags.SKIP_DIALOG_ENGINE, true)` to tell the Dialog Engine to skip the event processing. This is useful when your event is not a user message.
:::

## Webchat Events

There are currently 4 events that can be caught in your page:

| name            | Description                                                                   |
| --------------- | ----------------------------------------------------------------------------- |
| `webchatLoaded` | Triggered when the webchat is loaded and ready to be opened                   |
| `webchatOpened` | Triggered when the webchat button bubble is clicked                           |
| `webchatClosed` | Triggered when the webchat close button is clicked                            |
| `webchatReady`  | Triggered when the webchat is ready to accept events, like proactive triggers |

## Common Use Cases

### Send Message When the Webchat is Loaded

It sends an event when the webchat is loaded and ready to be opened.

Use this code in your `index.html`:

```html
<html>
  <head>
    <title>Embedded Webchat</title>
    <script src="/assets/modules/channel-web/inject.js"></script>
  </head>

  <body>
    This is an example of embedded webchat
  </body>

  <script>
    // Initialize the chat widget
    // Change the `botId` with the Id of the bot that should respond to the chat
    window.botpressWebChat.init({
      host: "http://localhost:3000",
      botId: "welcome-bot",
    })

    window.addEventListener("message", function (event) {
      if (event.data.name === "webchatReady") {
        window.botpressWebChat.sendEvent({
          type: "proactive-trigger",
          channel: "web",
          payload: { text: "fake message" },
        })
      }
    })
  </script>
</html>
```

### Send Message When Opening Webchat

It sends an event when the webchat button bubble is clicked.

Use this code in your `index.html`:

```html
<html>
  <head>
    <title>Embedded Webchat</title>
    <script src="/assets/modules/channel-web/inject.js"></script>
  </head>

  <body>
    This is an example of embedded webchat
  </body>

  <script>
    // Initialize the chat widget
    // Change the `botId` with the Id of the bot that should respond to the chat
    window.botpressWebChat.init({
      host: "http://localhost:3000",
      botId: "welcome-bot",
    })

    window.addEventListener("message", function (event) {
      if (event.data.name === "webchatOpened") {
        window.botpressWebChat.sendEvent({
          type: "proactive-trigger",
          channel: "web",
          payload: { text: "fake message" },
        })
      }
    })
  </script>
</html>
```

### Send Custom Content on Proactive Event

You can intercept a proactive trigger to send custom content. This could be used to send reminders, display a welcome message or ask for feedback.

- Make sure that you've sent an event from your webpage (see the examples above).
- Use this in your `before_incoming_middleware` hook:

```js
// Catch the event
if (event.type === "proactive-trigger") {
  const eventDestination = {
    channel: event.channel,
    target: event.target,
    botId: event.botId,
    threadId: event.threadId,
  }

  // Skip event processing
  event.setFlag(bp.IO.WellKnownFlags.SKIP_DIALOG_ENGINE, true)

  // Make the bot respond with custom content instead
  bp.cms
    .renderElement(
      "builtin_text",
      { text: "I'm so proactive!", typing: true },
      eventDestination
    )
    .then((payloads) => {
      bp.events.replyToEvent(event, payloads)
    })
}
```

Here we're using the [replyToEvent](https://botpress.com/reference/modules/_botpress_sdk_.events.html#replytoevent) function from the SDK to reply to the current event and [renderElement](https://botpress.com/reference/modules/_botpress_sdk_.cms.html#renderelement) to render our custom content.

### Send Proactive Only to New Users

When you want to respond only to new users, you have to check if their session is new. We can do that by looking at the session's last messages.

- Make sure that you've sent an event from your webpage (see the examples above).
- Use this code in your `before_incoming_middleware` hook:

```js
if (event.type === "proactive-trigger") {
  // We only want to trigger a proactive message when the session is new,
  // otherwise the conversation will progress every time the page is refreshed.
  if (event.state.session.lastMessages.length) {
    // This will tell the dialog engine to skip the processing of this event.
    event.setFlag(bp.IO.WellKnownFlags.SKIP_DIALOG_ENGINE, true)
  }
}
```
