Deploying to WebChat

Embed a fully customizable chat widget on your website with a single line of code.

Overview

WebChat allows you to embed a chat widget directly on your website. Visitors can interact with your flows without leaving your site, and conversations persist across page navigations and return visits.

Key Features

  • Single line of code to embed
  • Fully customizable appearance (colors, fonts, sizing)
  • Light and dark theme support with auto-detection
  • Mobile-responsive design
  • Conversation history persistence
  • Optional user info collection
  • JavaScript API for programmatic control

Create a WebChat Deployment

Creating a WebChat deployment is straightforward and doesn't require any external connections.

Step-by-Step Guide

Step 1: Choose Platform

  • Open your flow in the Flow Editor
  • Click "Deployments" in the toolbar (rocket icon)
  • Select the WebChat platform card

Step 2: Configure Deployment

Deployment Name: Give it a descriptive name (e.g., "Website Support Widget")
Version Strategy:
Latest Version - Auto-updates to newest published version
Pinned Version - Lock to specific version (requires manual updates)
Active: Check to enable immediately

Step 3: Customize Widget (Optional)

Click "Customize Widget" to open the visual customizer where you can configure colors, sizing, greeting messages, and more. See the Customization section for details.

Step 4: Get Embed Code

After creating the deployment, click the "Embed" button to view and copy your embed code.

Embed Code

Add the embed code to your website, just before the closing </body> tag:

<script
  async
  src="https://universalchatbot.com/chatbot.js"
  data-bot-url="https://universalchatbot.com/deployments/YOUR_ID/embed">
</script>

The script loads asynchronously and won't block your page from rendering. Once loaded, a chat widget button appears in the corner of your page (bottom-right by default).

Configuration in Embed Code

All widget configuration is embedded directly in the script tag as data attributes. When you customize your widget in the dashboard, the embed code automatically includes all your settings.

Mode

Where the conversation appears on the page. Set it under Widget → Mode in the widget customizer; the embed code updates to match.

Launcher (default)
A floating button in the corner of every page, which opens the conversation over your content. Nothing on your page has to make room for it.
Inline
The conversation renders inside an element you provide, as part of the page rather than floating above it. There is no launcher button and it is open from the moment the page loads. Inline adds no frame of its own, so the widget takes on whatever styling your container has.

Inline needs to know where to render, so the embed code includes a container and points at it with data-target:

<div id="universal-chatbot"></div>

<script
  async
  src="https://universalchatbot.com/chatbot.js"
  data-bot-url="https://universalchatbot.com/deployments/YOUR_ID/embed"
  data-mode="inline"
  data-target="#universal-chatbot">
</script>

Point data-target at any selector you like if you would rather place it yourself. The container needs no height: a card layout sizes the widget to the question on screen, so the element grows and shrinks as the conversation moves, and a chat layout uses the widget height from the customizer. Style the container for width, spacing and anything else you want around it.

Inline drops the widget's own chrome: no header, no launcher, no panel background, border, corners or shadow. Your container owns the frame, so style it to match the rest of your page. The header settings in the customizer (title, subtitle and the theme toggle) only apply to the launcher.

When the conversation starts

Inline waits for the visitor, because a conversation is a real thing on your account: it lands in your inbox for someone to read, and may count towards your usage. A page that inline sits on is loaded by everyone who visits, most of whom will scroll past, and you should not be paying for those.

How it waits depends on the layout. A card shows a button, labelled with your greeting. A chat shows its greeting above the message box and starts when the visitor writes, so typing is all it takes.

If you would rather it opened with the first question already asked, say so:

data-autostart="true"

A launcher ignores this and always starts, because opening it was the visitor asking.

Entry points

A flow can define entry points on its Start node: the ways in, each with its own path. On channels where a link can pre-fill a message they are matched against whatever the visitor arrives saying. On webchat there is no such link, so the widget offers them instead.

Card
Your greeting becomes the question and the entry points become the answers, with "Something else" alongside them for a reason that is not on the list.
Chat
They appear as replies under the greeting. Free text stays available: a visitor who types instead takes the default path with their own words as the first message.

Picking one sends it as the first message, exactly as a campaign link would, so the flow branches the same way on every channel. Nothing is created until someone picks.

Entry points come before autostart. A flow that asks how to begin has to be allowed to ask it, so where they exist the widget always offers them, including in a launcher. That also means a launcher stops creating a conversation merely because someone opened it.

Start Over returns to the entry points too, since starting again is a new conversation and it should begin the way the first one did.

Mode and layout are separate choices

Mode is where the conversation sits on your page. Layout, below, is how it presents the flow. Any combination works: a card inline for a form on a landing page, or a card in the launcher for a short intake in the corner.

Layouts

A webchat deployment presents its flow in one of two layouts. Set it under Widget → Layout in the widget customizer.

Chat (default)
Messages stream into a scrolling thread, the way a chat with a person looks. Best when the conversation is open-ended and the reader may ask anything.
Card
One question per screen, with the previous answers behind it. Best when the flow is a set of questions someone is trying to get through, such as qualifying a lead or collecting details before a handover.

Card layout suits a form, not a chat

On a form somebody is trying to finish, waiting for each message to arrive costs completions. The card shows the whole question at once and moves on as soon as it is answered. A visitor who leaves partway through picks up where they stopped when they come back.

The four combinations

Mode and layout are set independently, so every pairing is available. What each one is like to meet:

Combination Starts Height
Launcher + chat
The familiar corner widget.
On open Widget height
Launcher + card
A short intake in the corner.
On open Widget height
Inline + card
A form in the page. Shows a button labelled with your greeting.
On the button Follows the question
Inline + chat
A conversation in the page. Shows your greeting above the message box.
When the visitor writes Widget height

Only a card knows how tall it is, because it shows one question at a time. A chat is a scrolling thread with no natural end, so inline it takes the widget height from the customizer and your container should leave room for it.

Customization

The widget customizer provides a visual interface to configure every aspect of your chat widget's appearance and behavior.

Testing a draft flow uses its own widget settings, separate from any deployment. Open Test in the flow editor and use the palette button to change them, so you can try a layout or a colour scheme before committing it to a deployment, or before the flow is deployed at all.

Theme & Colors

The widget supports both light and dark themes with automatic detection and full color customization.

Theme Mode

light
Always use light theme
dark
Always use dark theme
system*
Follow user's OS preference (prefers-color-scheme)
tailwind_class*
Match Tailwind's dark mode class on your html/body element

* Reactive: automatically updates when value changes

Color Theme Presets

Start with one of our professionally designed presets:

  • Modern Slate - Professional, neutral tones
  • Professional Indigo - Bold corporate look
  • Ocean Blue - Calming, friendly feel
  • Fresh Emerald - Natural, sustainable vibe
  • Elegant Rose - Luxury, premium appearance
  • Warm Amber - Inviting, approachable style
  • Custom - Full control over every color

Color Variables

Each theme (light and dark) has its own set of customizable colors:

primaryColor
Main interactive color (buttons, links)
primaryHoverColor
Hover state for primary elements
accentColor
Secondary accent color
headerColor
Widget header background
launcherColor
Floating launcher button color
botMessageBackgroundColor
Background for bot messages
botMessageTextColor
Text color for bot messages
botMessageTextSecondaryColor
Secondary text color for bot messages (timestamps)
userMessageBackgroundColor
Background for user messages
userMessageTextColor
Text color for user messages
userMessageTextSecondaryColor
Secondary text color for user messages (timestamps)
backgroundColor
Main chat area background
surfaceColor
Input area and card surfaces
surfaceTextColor
Text color on surface elements
borderColor
Borders and dividers

Appearance

Font Family
CSS font-family string (defaults to system fonts). Name a Google font and it is loaded for you. Anything else renders only for visitors who already have it installed, so use a system stack such as Georgia, serif if you are not naming a Google font.
Font Size
Base font size for messages (default: 16px)
Border Radius
Corner roundness for the widget and messages (default: 16px)

Widget

Mode
Launcher or Inline (default: Launcher). See Mode above
Layout
Chat or Card (default: Chat). See Layouts below
Title
Header title shown when widget is open (e.g., "Chat with us")
Subtitle
Secondary text below the title (e.g., "We'll reply as soon as we can")
Widget Width
Width of the open widget (default: 400px)
Widget Height
Height of the open widget (default: 600px)
Button Size
Size of the floating launcher button (default: 60px)
Position
Which corner the launcher button sits in: bottom-right, bottom-left, top-right, or top-left. Launcher only, since inline has no button.

Effects

Shadow Strength
Widget shadow intensity: light, medium, or strong
Backdrop Blur
Apply a blur effect to the background behind the widget
Animations
Animation style: minimal (subtle), smooth (balanced), or playful (bouncy)

Greeting

The greeting is how a visitor learns what the conversation is for before they commit to it. Every mode uses the same sentence, in the way that mode has to say it:

Launcher
A bubble beside the button, after the delay below.
Inline chat
The opening line in the transcript, standing in for the question the flow has not asked yet.
Inline card
The label on the start button, so it says what the visitor is starting rather than "Start".

Write it as an invitation and it works in all three: See how it qualifies a lead reads as well on a button as it does in a bubble. Leave it empty and the card falls back to "Start" and the inline chat opens on an empty panel.

Greeting Message
The sentence itself (e.g., "Hi! How can I help you today?")
Greeting Delay
Milliseconds to wait before the launcher bubble appears (default: 3000ms). Inline shows the greeting straight away, since it is already on the page.
Show Greeting
Enable or disable the launcher bubble. Inline is unaffected: with nothing to say, a waiting card has no label and a waiting chat has no opening line.

User Info Collection

Optionally collect user information before or during the conversation. This data becomes available as variables in your flow.

Collection Timing

never
Don't collect user info (default)
before_chat
Show form before the user can start chatting
after_first_message
Show form after user sends their first message

Available Fields

Select which fields to collect:

  • Name - User's name
  • Email - Email address with validation
  • Phone - Phone number with international format support

Each field can be marked as required or optional. Users can skip optional fields.

Accessing Collected Info

Collected user information is available in your flow via {{@request.user.name}}, {{@request.user.email}}, and {{@request.user.phone}}.

JavaScript API

Control the widget programmatically using the global UCBChatbotWidget object. This is how you open the chat from your own button, link or menu item rather than the floating launcher.

Available Methods

UCBChatbotWidget.open()
Open the chat widget
UCBChatbotWidget.close()
Close the chat widget
UCBChatbotWidget.toggle()
Toggle between open and closed states
UCBChatbotWidget.isOpen()
Returns true if widget is currently open
UCBChatbotWidget.setUnreadCount(n)
Set the unread message badge count

Example Usage

// Open chat when user clicks a custom button
document.getElementById('help-button').addEventListener('click', () => {
  UCBChatbotWidget.open();
});

// Open chat automatically after 30 seconds
setTimeout(() => {
  if (!UCBChatbotWidget.isOpen()) {
    UCBChatbotWidget.open();
  }
}, 30000);

// Open as soon as the widget exists, e.g. arriving from a "chat with us" link
function whenChatReady(callback) {
  if (window.UCBChatbotWidget) return callback(window.UCBChatbotWidget);
  const timer = setInterval(() => {
    if (window.UCBChatbotWidget) {
      clearInterval(timer);
      callback(window.UCBChatbotWidget);
    }
  }, 100);
}

if (location.hash === '#chat') {
  whenChatReady((widget) => widget.open());
}

More than one bot on a page

UCBChatbotWidget points at whichever widget loaded last, which is all you need when the page carries one bot. Where a page runs two, reach for them by the bot URL you embedded them with.

// Keyed by the same URL as data-bot-url on the script tag
const sales = UCBChatbotWidgets['https://universalchatbot.com/deployments/YOUR_ID/embed'];
sales.open();

A widget is removed from both handles when it is taken off the page, so anything you hold on to should be read fresh rather than stored.

Wait for Widget Ready

The embed script is async, so UCBChatbotWidget does not exist the moment your page runs. Calling it from a click handler or a timer is safe, because the widget has loaded by then. Calling it directly during page load will fail. To open the chat straight away, poll for it as the last example above shows.

Request a demo
This form is running on UniversalChatbot.