Skip to content

Setting up the Embedded Chat

The embedded chat shows the AI Support chat bubble on another website, such as a public marketing site or a documentation portal, so that people who are not users of the application can talk to an assistant. It is the same bubble that application users see, described in The Chat Bubble, packaged as an HTML element, <ai-support-chat>, that any site can include regardless of the technology it is built with.

Visitors do not sign in. Each browser is recognised by a cookie and appears in the application as a user named visitor- followed by a short code. Every site is connected through a web channel, which sets the assistant its visitors talk to. Their conversations become regular sessions of that channel: operators can read them, join them, take them over from the assistant, and answer them from the host application like any other conversation.

Free mode

The embedded chat is available in free mode. Messages exchanged through it count toward the same daily messaging limit as the rest of the chat. See Licensing for details.

What you will learn

This guide covers the whole setup, end to end: choosing the host the chat is served from, configuring the host application, creating the web channel, adding the element to the site, and keeping the chat protected and tidy once it is live.

How a conversation travels

  1. A visitor opens a page of the site that includes <ai-support-chat>.
  2. The page loads the chat from a chat host: a host name of the site's own domain that points to the host application, such as chat.example.com for example.com.
  3. AI Support recognises the visitor's browser by its cookie, finds the enabled web channel of the site, and shows the bubble.
  4. The visitor writes. The message is stored in a session of the web channel, and the channel's assistant answers it — unless the session has been switched to manual.
  5. Operators follow the conversation from the Chat view of the host application, and can answer it themselves.

Before you start

Make sure you have the following in place:

  • The host application served over HTTPS. The visitor cookie is only sent over HTTPS. Plain HTTP is supported only for local tests, by turning off secure-cookie (see the application properties).
  • A host name of the site's domain that can point to the host application. You will dedicate it to the chat in Step 1.
  • Access to the site's HTML, to add the element to its pages.
  • At least one assistant configured in AI Support — it will be answering the visitors.
  • An upgraded database. If the application was upgraded from AI Support 2.1.0 or earlier, its developers must apply the upgrade notes first: until then, the database refuses to save a web channel.

Application properties

The embedded chat is configured through the following application properties:

Property Purpose Default
appjars.aisupport.integrations.embedded-chat.enabled Serves <ai-support-chat> false
appjars.aisupport.integrations.embedded-chat.hosts Chat hosts, comma-separated. Required when the chat is enabled —
appjars.aisupport.integrations.embedded-chat.visitor-key Secret of at least 32 characters that visitor names are derived from. Required when the chat is enabled; changing it renames every visitor, who then lose their earlier conversations —
appjars.aisupport.integrations.embedded-chat.secure-cookie Sends the visitor cookie only over HTTPS. Turn it off only for local tests over plain HTTP true
appjars.aisupport.integrations.embedded-chat.features.attachments Lets visitors attach files false
appjars.aisupport.integrations.embedded-chat.features.mentions Lets visitors mention users false
appjars.aisupport.integrations.embedded-chat.features.session-filter Shows the conversation filter in the bubble false
appjars.aisupport.integrations.embedded-chat.features.chat-links Offers links to conversations in the host application false
appjars.aisupport.integrations.embedded-chat.fab-position-memory How long the bubble stays where a visitor dragged it after they leave the site 2m
appjars.aisupport.integrations.embedded-chat.limits.visitor-per-minute Messages a visitor may send each minute; 0 for unlimited 12
appjars.aisupport.integrations.embedded-chat.limits.visitor-per-hour Messages a visitor may send each hour; 0 for unlimited 40
appjars.aisupport.integrations.embedded-chat.limits.address-per-hour Messages all visitors from one network address may send each hour; 0 for unlimited 100
appjars.aisupport.integrations.embedded-chat.limits.per-day Messages all visitors together may send each day; 0 for unlimited 2000
appjars.aisupport.integrations.embedded-chat.purge.schedule Cron expression for deleting visitor sessions nobody has written in for a while (unset — never)
appjars.aisupport.integrations.embedded-chat.purge.zone Time zone of the purge schedule UTC
appjars.aisupport.integrations.embedded-chat.purge.after-inactivity How long a web channel session is kept after its last message 90d
appjars.aisupport.integrations.embedded-chat.purge.max-per-run Sessions deleted per run; -1 for unlimited -1
appjars.aisupport.chat.max-context-length Longest context a page can send with each message; longer ones are cut 500

The developer-oriented reference for these properties is in the Developer Guide.

Step 1 — Choose the chat host

The chat must be served from a host of the site's own domain, such as chat.example.com for a site at example.com, pointing to the host application. Browsers do not send cookies to another site, and without its cookie a visitor would lose their conversations on every page.

That host is dedicated to the chat. AI Support answers only the requests the chat needs on it; the login page, the views and everything else of the application answer not found there. This keeps the site's scripts, which are allowed to read the chat's responses, away from any application session. The application must therefore stay reachable for its own users through another host name.

Create the DNS record for the chat host, and route it to the host application exactly as its main host is routed. If a reverse proxy sits in front of the application, it must pass the original host name along: AI Support recognises the chat host by the name the request was sent to, and when it does not match, the chat does not load.

Copy for later: the chat host, such as chat.example.com.

Step 2 — Configure the host application

Add the following properties, using your own chat host and a random secret of at least 32 characters:

appjars.aisupport.integrations.embedded-chat.enabled=true
appjars.aisupport.integrations.embedded-chat.hosts=chat.example.com
appjars.aisupport.integrations.embedded-chat.visitor-key=<a random secret of at least 32 characters>

The application does not start when the chat is enabled without hosts, or with a visitor key that is missing or shorter than 32 characters. Keep the visitor key secret and stable: visitor names are derived from it, so changing it gives every visitor a new name, and their earlier conversations no longer appear in their bubble.

Two changes in the application's code are also needed. Ask its developers to make them:

  1. Let the chat through the security configuration. Requests to /web-component/** must be allowed without signing in.
  2. Make Vaadin find the chat element when the application's main class is in a package outside com.appjars.aisupport.flow.embed. Vaadin registers the element only from the packages it scans; otherwise the chat script answers with the application's page instead. @EnableVaadin replaces the default scan, so the application's own packages must be listed too:

    @SpringBootApplication
    @EnableVaadin({"com.example", "com.appjars.aisupport.flow.embed"})
    public class Application { }
    

Restart the application after these changes.

Step 3 — Create the web channel

In the Channels view of the host application (default route as/channels), click + Channel and select the Web tab. (Field-by-field details live in the Channels view reference.)

  • Name (required): A unique name for the channel, such as the site's name.
  • Enabled: Leave it on. Only sites with an enabled web channel can load the chat.
  • Assistant (required): The assistant the site's visitors talk to.
  • Site address (required): The address of the site, with its scheme and nothing after the host, such as https://example.com.

Click Save. The channel appears in the grid with an Enabled status, and its site in the Identifier column.

The site address must be the one visitors see in their browser, including www. when the site uses it. A site reachable both as https://example.com and as https://www.example.com needs a web channel for each, and each site can belong to a single channel. Turning the channel off takes the chat off its site.

Step 4 — Add the chat to the site

Add the element and its script to every page that should show the chat, with the element as a direct child of <body>:

<ai-support-chat language="en"></ai-support-chat>
<script type="module" src="https://chat.example.com/web-component/ai-support-chat.js"></script>

Replace chat.example.com with your chat host. The bubble floats over the page, so the element must not be placed inside an element that applies a CSS transform, filter or containment, which would trap it.

The element takes three optional attributes:

  • language: The language the chat is shown in, as a language tag such as en or es. It is read when the chat loads, so set it to the language of the page.
  • context: What the page is about, such as context="Pricing - https://example.com/pricing/". It is sent to the assistant with every message the visitor writes, so the assistant knows where the visitor is. It is cut to 500 characters by default. A single-page application can update it as the visitor navigates.
  • theme: Set theme="dark" to show the chat in the dark theme. The page can also restyle the chat through Lumo's CSS custom properties, set on ai-support-chat.

Step 5 — Protect and maintain the chat

The chat is open to anyone who visits the site, so it comes with limits and a clean-up that are worth reviewing before going live.

Visitor limits

The limits.* properties cap how many messages visitors can send: each visitor per minute and per hour, all visitors from one network address per hour, and all visitors together per day. A visitor who reaches a limit loses the bubble: the message is dropped, the bubble hides for the rest of that page, and pages loaded before the limit's period ends show none. The counts are kept in memory and start over when the application restarts.

Behind a reverse proxy, the application must see the visitors' real addresses, which in Spring Boot is configured with server.forward-headers-strategy. Otherwise every visitor appears to come from the proxy and they all share one address limit. The proxy is also the right place to cap the rate and the body size of the requests to the chat host.

Removing old conversations

Visitors are anonymous, so nobody can ask for their conversations to be removed. Set purge.schedule to delete web channel sessions in which nobody has written for purge.after-inactivity (90 days by default):

appjars.aisupport.integrations.embedded-chat.purge.schedule=0 0 3 * * *

The clean-up schedules itself; it runs even when the application does not enable scheduling.

Warning

The clean-up permanently deletes the web channel sessions it selects, with all their messages and attachments. It applies to every web channel of the application.

Step 6 — Test the integration

Open a page of the site in a browser and verify each link of the chain:

  1. The bubble appears on the page, in the language set on the element.
  2. A session is created when you send a message: it appears in the Chat view of the host application, started by a visitor-… user and linked to the web channel.
  3. The assigned assistant replies, and the reply appears in the bubble on the site.
  4. An operator can answer manually from the session, and the answer reaches the visitor.
  5. The conversation survives navigation: open another page of the site, and the same conversation is still there.

If any check fails, see Troubleshooting below.

Troubleshooting

The bubble does not appear

  • Check the channel. It must be Enabled, and its Site address must match the page's address exactly: scheme, host, and port. The application logs a warning naming the address of a page whose site has no enabled web channel.
  • Check the property. The chat is served only when embedded-chat.enabled is true. When the element loads while the integration is disabled, the application logs a warning and the element stays empty.
  • Open the script address in a browser. If https://chat.example.com/web-component/ai-support-chat.js shows the application's page instead of a script, Vaadin is not scanning the chat element (Step 2). If it asks to sign in, the security configuration does not let /web-component/** through.
  • Check the chat host. If the browser reports a blocked cross-origin request, the request did not reach the application under a host listed in hosts, usually because a reverse proxy replaces the host name.
  • Check the limits. A visitor who has reached a limit does not get the bubble until the limit's period has passed.

Visitors lose their conversations

  • The chat host is on another domain. Browsers withhold the visitor cookie from a host of another site. Serve the chat from a host of the site's own domain (Step 1).
  • The site is tested over plain HTTP. The secure cookie is only sent over HTTPS; for local tests, turn off secure-cookie.
  • The visitor key changed. Every visitor got a new name, and their earlier conversations remain in the application under the old one.

Every visitor reaches the limit at once

The application sees every visitor with the proxy's address, so they all share the address limit. Configure server.forward-headers-strategy as described in Visitor limits.

Further reading