@nexvio-ai/widget-js
v0.1.0
Published
Embeddable Nexvio chat widget custom element and React bindings.
Maintainers
Readme
Nexvio Widget JS
Embeddable JavaScript SDK that renders the Nexvio chat experience inside any web application. The package exposes two custom elements:
<nexvio-chat-widget>- Direct widget embed (for custom integrations)<nexvio-chat-bot>- Floating chat button with animated widget (recommended)
Plus React bindings for developers who prefer declarative integrations.
Installation
pnpm add @nexvio-ai/widget-jsThe package ships ESM, CJS, and type declarations. React bindings are exposed
via the @nexvio-ai/widget-js/react subpath export.
Quick Start
Using <nexvio-chat-bot> (Recommended)
The easiest way to add a chat widget to your site is using <nexvio-chat-bot>, which
provides a floating chat button and automatically manages the widget container.
import '@nexvio-ai/widget-js';
const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({ publicKey: 'pk_test-123' });
document.body.append(chatbot);React:
import { NexvioChatbot } from '@nexvio-ai/widget-js/react';
export function App() {
return (
<NexvioChatbot
options={{
publicKey: 'pk_test-123',
onEvent: (event) => console.log(event.name, event.detail),
}}
/>
);
}Using <nexvio-chat-widget> (Advanced)
For custom integrations where you want full control over the widget container,
use <nexvio-chat-widget> directly.
import '@nexvio-ai/widget-js';
const widget = document.createElement('nexvio-chat-widget');
widget.setOptions({ publicKey: 'pk_test-123' });
document.body.append(widget);React:
import { NexvioWidget } from '@nexvio-ai/widget-js/react';
export function SupportWidget() {
return (
<NexvioWidget
options={{
publicKey: 'pk_test-123',
onEvent: (event) => console.log(event.name, event.detail),
}}
className="h-full w-full"
/>
);
}<nexvio-chat-bot> Options
The chatbot element extends all widget options and adds the following:
Chatbot-Specific Options
position('bottom-right' | 'bottom-left' | 'top-right' | 'top-left') - Position of the chat button. Default:'bottom-right'defaultOpen(boolean) - Whether the widget should be open initially. Default:falsebuttonColor(string) - Background color of the chat button. Default:'#3B82F6'badge(number | boolean) - Show a notification badge. Pass a number for unread count, ortruefor a dot. Default:falsebuttonIcon(string) - Custom SVG icon for the button (replaces default chat icon)gap(number) - Gap from screen edge in pixels. Default:20
Widget Options (Inherited)
All options from <nexvio-chat-widget> are supported:
publicKey(required) – widget identifier used by the Nexvio platformappearance– overrides for colours, fonts, or density. Values are passed to the hosted widget framemetadata/context– arbitrary JSON forwarded downstreamclientActions– map of callbacks that can be invoked by the iframe for client-side behaviour (e.g. analytics, navigation)onEvent– receives all events emitted by the widget (ready, error, custom events defined in the workspace)fetch– customfetchimplementation used when the frame requests server-side actions through the hostclient.tools– client-side tools that can be called by the AIstartScreen– configuration for the initial greeting screen
Example: Full Configuration
const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({
publicKey: 'pk_test-123',
position: 'bottom-right',
buttonColor: '#6366F1',
badge: 3, // Show unread count
defaultOpen: false,
gap: 24,
appearance: {
colorScheme: 'light',
},
context: {
visitor: {
name: 'John Doe',
email: '[email protected]',
},
},
onEvent: (event) => {
console.log('Widget event:', event.name, event.detail);
},
});
document.body.append(chatbot);Programmatic Control
Methods
const chatbot = document.querySelector('nexvio-chat-bot');
// Open the widget
chatbot.open();
// Close the widget
chatbot.close();
// Toggle open/closed state
chatbot.toggle();
// Check if open
console.log(chatbot.isOpen); // boolean
// Access the underlying widget element
const widget = chatbot.widget;
widget?.focusInput();
widget?.setVisitor({ name: 'Jane Doe' });Events
const chatbot = document.querySelector('nexvio-chat-bot');
// Listen to chatbot-specific events
chatbot.addEventListener('chatbot.opened', () => {
console.log('Chat opened');
});
chatbot.addEventListener('chatbot.closed', () => {
console.log('Chat closed');
});
// Listen to widget events (forwarded from the widget)
chatbot.addEventListener('nexvio.event', (event) => {
console.log('Widget event:', event.detail);
});React Usage
Basic Example
import { NexvioChatbot } from '@nexvio-ai/widget-js/react';
import { useRef } from 'react';
export function App() {
const chatbotRef = useRef<NexvioChatbotElement>(null);
return (
<>
<button onClick={() => chatbotRef.current?.open()}>
Open Chat
</button>
<NexvioChatbot
ref={chatbotRef}
options={{
publicKey: 'pk_test-123',
buttonColor: '#6366F1',
badge: 3,
}}
/>
</>
);
}With Event Handling
import { NexvioChatbot } from '@nexvio-ai/widget-js/react';
import type { NexvioWidgetEvent } from '@nexvio-ai/widget-js';
export function App() {
const handleEvent = (event: NexvioWidgetEvent) => {
console.log('Event:', event.name, event.detail);
};
return (
<NexvioChatbot
options={{
publicKey: 'pk_test-123',
onEvent: handleEvent,
appearance: {
colorScheme: 'dark',
},
}}
/>
);
}Using the Hook
import { useNexvioChatbot } from '@nexvio-ai/widget-js/react';
import { useEffect } from 'react';
export function App() {
const { ref, setElement } = useNexvioChatbot({
publicKey: 'pk_test-123',
buttonColor: '#6366F1',
});
useEffect(() => {
// Access the element via ref.current
const chatbot = ref.current;
if (chatbot) {
chatbot.open();
}
}, []);
return <nexvio-chat-bot ref={setElement} />;
}<nexvio-chat-widget> Options
For direct widget usage, see the widget-specific options:
publicKey(required) – widget identifier used by the Nexvio platformappearance– overrides for colours, fonts, or density. Values are passed to the hosted widget framemetadata/context– arbitrary JSON forwarded downstreamclientActions– map of callbacks that can be invoked by the iframe for client-side behaviour (e.g. analytics, navigation)onEvent– receives all events emitted by the widget (ready, error, custom events defined in the workspace)fetch– customfetchimplementation used when the frame requests server-side actions through the hostmessageActions– per-message UI action toggles (copy, feedback, retry)client.tools– client-side tools that can be called by the AIstartScreen– configuration for the initial greeting screen
Styling
CSS Custom Properties
The chatbot element exposes CSS custom properties for styling:
nexvio-chat-bot {
--chatbot-button-size: 60px;
--chatbot-button-bg: #3B82F6;
--chatbot-button-color: white;
--chatbot-widget-width: 420px;
--chatbot-widget-height: 600px;
--chatbot-widget-gap: 20px;
}Responsive Behavior
On mobile devices (screen width ≤ 768px), the widget automatically switches to full-screen mode for better usability.
Development
pnpm install
pnpm --filter @nexvio-ai/widget-js test
pnpm --filter @nexvio-ai/widget-js buildThe build pipeline uses tsup to emit bundled ESM/CJS outputs with type
declarations. Vitest covers the base utilities used to exchange data with the
hosted iframe.
Demo Integration
The monorepo includes a live integration at
apps/demo-app/src/app/widget/page.tsx. Launch it with:
pnpm --filter demo-app devThe demo renders <NexvioWidget />, lets you swap the widget public key, and
mirrors all bridge events in a side panel so you can validate host/widget
communication in real time.
Migration Guide
From <nexvio-chat-widget> to <nexvio-chat-bot>
If you're currently using <nexvio-chat-widget> and want to switch to the chatbot:
Before:
const widget = document.createElement('nexvio-chat-widget');
widget.setOptions({ publicKey: 'pk_test-123' });
document.body.append(widget);After:
const chatbot = document.createElement('nexvio-chat-bot');
chatbot.setOptions({ publicKey: 'pk_test-123' });
document.body.append(chatbot);All widget options work the same way. The chatbot automatically creates and manages the widget internally.
TypeScript Support
Full TypeScript support is included:
import type {
NexvioWidgetOptions,
NexvioWidgetEvent,
NexvioChatbotOptions,
} from '@nexvio-ai/widget-js';
import type { NexvioChatbotElement } from '@nexvio-ai/widget-js';Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
Requires support for:
- Custom Elements (Web Components)
- Shadow DOM
- ES2017+ features
