Skip to main content

Embed Chat with DIAL Overlay

In this tutorial, you will embed DIAL Chat in a static HTML page using the DIAL Overlay library. By the end, you will have a host page that loads Chat in an iframe, sends a message programmatically, and listens for generation events.

Prerequisites​

  • A running DIAL instance with DIAL Chat
  • Node.js 18+ installed
  • Basic familiarity with HTML and TypeScript

What you will build​

A minimal web page that embeds DIAL Chat as an overlay widget. The host page will:

  • Display DIAL Chat in a wide iframe
  • Send a message to the active conversation via the Overlay API
  • Log an event to the browser console when the model starts generating

Project structure​

By the end of this tutorial, your project will look like this:

dial-overlay-demo/
├── package.json
├── index.html
└── src/
└── main.ts

Step 1: Configure DIAL Chat for overlay mode​

Add the following environment variables to your DIAL Chat deployment. If you use Docker Compose, update the chat service in your docker-compose.yml:

chat:
image: epam/ai-dial-chat:0.41.7
platform: linux/amd64
environment:
IS_IFRAME: "true"
ALLOWED_IFRAME_ORIGINS: "http://localhost:5173"
ALLOW_OPEN_SIGNIN_PAGE_IN_IFRAME: "true"

ALLOWED_IFRAME_ORIGINS must match the origin where your host page will run. The Vite dev server used later in this tutorial defaults to http://localhost:5173.

Restart the Chat container after changing the configuration.

Verify: DIAL Chat starts without errors. Open http://localhost:3000 in a browser—Chat loads normally, but it is now also available for iframe embedding.

Step 2: Scaffold the host project​

Create a new directory and initialize a Node.js project:

mkdir dial-overlay-demo && cd dial-overlay-demo
npm init -y

Install the Overlay library and a development server:

npm install @epam/ai-dial-overlay@0.9.0
npm install --save-dev vite@6.3.5 typescript@5.8.3

Verify: node_modules/@epam/ai-dial-overlay exists and package.json lists both dependencies.

Step 3: Create dial-overlay-demo/index.html​

Create dial-overlay-demo/index.html with a container element for the overlay:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>DIAL Overlay Demo</title>
<style>
#chat-container {
width: 100%;
height: 600px;
border: 1px solid #ccc;
}
</style>
</head>
<body>
<h1>DIAL Overlay Demo</h1>
<div id="chat-container"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

Step 4: Create dial-overlay-demo/src/main.ts​

Create dial-overlay-demo/src/main.ts with the Overlay initialization logic:

import { ChatOverlay } from '@epam/ai-dial-overlay';

const container = document.getElementById('chat-container');
if (!container) {
throw new Error('Container element not found');
}

const overlay = new ChatOverlay(container, {
hostDomain: window.location.origin,
domain: 'http://localhost:3000', // your DIAL Chat overlay instance
theme: 'light',
modelId: 'gpt-4o', // replace with a model deployed in your DIAL instance
});

await overlay.ready();
console.log('Overlay is ready');

This creates an iframe inside the container, waits for the DIAL Chat handshake to complete, and logs a message to the console.

Verify: No verification yet—the dev server is not running. Continue to step 5.

Step 5: Start the dev server and verify the overlay​

Start the Vite development server:

npx vite

Open http://localhost:5173 in a browser.

Verify: The page displays the heading "DIAL Overlay Demo" and an embedded DIAL Chat interface inside the bordered container. The browser console shows Overlay is ready.

Step 6: Send a message programmatically​

Add the following lines to dial-overlay-demo/src/main.ts, after the await overlay.ready() call:

const sendButton = document.createElement('button');
sendButton.textContent = 'Send greeting';
sendButton.addEventListener('click', async () => {
await overlay.sendMessage('Hello from the host application!');
console.log('Message sent');
});
document.body.insertBefore(sendButton, container);

Verify: Reload the page. Click the "Send greeting" button. The message "Hello from the host application!" appears in the embedded Chat conversation, and the model responds. The console shows Message sent.

Step 7: Subscribe to generation events​

Add the following lines to dial-overlay-demo/src/main.ts, after the button code:

const unsubscribe = overlay.subscribe(
'@DIAL_OVERLAY/GPT_START_GENERATING',
() => {
console.log('Model started generating a response');
}
);

Verify: Reload the page and send a message. The browser console shows Model started generating a response each time the model begins generating.

Step 8: Retrieve conversation messages​

Add the following lines to dial-overlay-demo/src/main.ts:

const fetchButton = document.createElement('button');
fetchButton.textContent = 'Get messages';
fetchButton.addEventListener('click', async () => {
const { messages } = await overlay.getMessages();
console.log('Conversation messages:', messages);
});
document.body.insertBefore(fetchButton, container);

Verify: Click "Get messages" after a conversation exchange. The browser console logs an array of message objects from the active conversation.

What you learned​

  • How to configure DIAL Chat for overlay mode using IS_IFRAME and ALLOWED_IFRAME_ORIGINS
  • How to create a ChatOverlay instance and wait for the iframe handshake
  • How to send messages and retrieve conversation history programmatically
  • How to subscribe to overlay events

Further reading​