Skip to main content

Embed DIAL Chat in a web page

Embed a running DIAL Chat in a small host page with @epam/ai-dial-chat-overlay, then send it a message from the host. This guide is for developers who know JavaScript and npm. It assumes DIAL Chat 1.x runs locally in Docker Compose at http://localhost:3000, for example from ai-dial-samples.

Prerequisites​

  • DIAL Chat 1.x in Docker Compose, with a working sign-in.
  • Node.js and npm, in a version that Vite supports.

This guide uses localhost on purpose: for local HTTP, the session cookie is SameSite=Lax, so the host page and Chat must be on the same site, and ALLOWED_IFRAME_ORIGINS must match the exact origin in the browser's address bar.

Steps​

1. Allow the host origin in DIAL Chat​

Add two variables to the chat service in your docker-compose.yml:

chat:
environment:
OVERLAY_ENABLED: "true"
ALLOWED_IFRAME_ORIGINS: "http://localhost:5173"

Recreate the container so it reads them:

docker compose up -d --force-recreate chat

2. Create the host project​

npm create vite@latest overlay-app -- --template vanilla
cd overlay-app
npm install
npm install @epam/ai-dial-chat-overlay@1.2.22

Use the overlay package version that matches your DIAL Chat release.

overlay-app/
├── index.html
├── package.json
└── src/
├── main.js
└── style.css

3. Write overlay-app/src/main.js​

Replace the file's content:

import './style.css';
import {
ChatOverlay,
OverlayEventType,
OverlayFeature,
} from '@epam/ai-dial-chat-overlay';

document.querySelector('#app').innerHTML = `
<h1>Overlay demo</h1>
<button id="ask" disabled>Ask DIAL</button>
<div id="chat-root" style="width: 400px; height: 600px;"></div>
`;

const run = async () => {
const overlay = new ChatOverlay('#chat-root', {
domain: 'http://localhost:3000',
requestTimeout: 20000,
// Keep the loader until the first conversation is ready to use.
loaderHideEvent: OverlayEventType.ReadyToInteract,
loaderStyles: { background: 'black' },
// Replaces the default feature set, so list every feature to keep.
enabledFeatures: [
OverlayFeature.Header,
OverlayFeature.ConversationsSection,
OverlayFeature.Likes,
],
});

overlay.subscribe(OverlayEventType.GptEndGenerating, async () => {
const { messages } = await overlay.getMessages();
console.log('Last message:', messages.at(-1));
});

await overlay.ready();

const ask = document.querySelector('#ask');
ask.disabled = false;
ask.addEventListener('click', () => overlay.sendMessage('What can you do?'));
};

run();

4. Start the host page​

npm run dev

Open http://localhost:5173. Chat loads in the frame; if you are not signed in, select Log in, finish the login in the new tab, and return. When the loader disappears, select Ask DIAL.

Result​

The host page shows DIAL Chat in a 400 × 600 frame. Ask DIAL sends a message from the host, and the browser console logs the answer when the generation ends.

If the frame stays empty, check the browser console: a CSP frame-ancestors error means OVERLAY_ENABLED or ALLOWED_IFRAME_ORIGINS does not match the host origin.

Coming from the legacy overlay​

Older samples use @epam/ai-dial-overlay with IS_IFRAME, hostDomain, and string feature names such as prompts-section, top-settings, footer, or request-api-key. With Chat 1.x:

  • Install @epam/ai-dial-chat-overlay and set OVERLAY_ENABLED instead of IS_IFRAME.
  • Drop hostDomain; the library sends window.location.origin itself.
  • Pass OverlayFeature values. Several legacy keys are gone or renamed; see UI feature keys.

Further reading​