Constructor
Create a widget instance by passing a VIZOCHOKWidgetConfig object to the constructor:
import { VIZOCHOKWidget } from '@vizochok/widget';
const widget = new VIZOCHOKWidget({
apiKey: 'pk_your_public_key',
storeId: 'your-store-id',
});
widget.mount();
The constructor validates that apiKey and storeId are provided and throws an Error immediately if either is missing.
Config Options
Required
| Property | Type | Description |
|---|
apiKey | string | Public API key issued from the VIZOCHOK admin panel. Must start with pk_. |
storeId | string | Unique store identifier. Used for session scoping and webhook routing. |
Optional — Identity & Locale
| Property | Type | Default | Description |
|---|
userId | string | undefined | Authenticated user ID. Enables personalization, per-user rate limits, and user profile loading. |
language | 'uk' | 'en' | 'ru' | 'uk' | UI language for error messages, status indicators, and placeholder text. |
apiBase | string | 'https://api.vizochok.com' | API base URL. Override for self-hosted or staging environments. |
Optional — Appearance
| Property | Type | Default | Description |
|---|
theme | ThemeConfig | undefined | Theme customization object. See ThemeConfig below. |
position | 'bottom-right' | 'bottom-left' | 'bottom-right' | Screen position of the floating toggle button and chat panel. |
botName | string | 'Помічник' | Display name shown in the chat header. |
botAvatar | string | undefined | URL of an avatar image displayed in the chat header. Falls back to a letter icon when not set. |
placeholder | string | undefined | Custom placeholder text for the message input field. |
welcomeMessage | string | undefined | Welcome text displayed when the chat is opened with no messages. |
Optional — Callbacks
| Property | Type | Description |
|---|
onCartChanged | (cart: CartChangedEvent) => void | Fired when the AI adds, removes, or updates items in the cart. Use this to sync your store’s cart UI. |
onProductClick | (product: ProductItem) => void | Fired when a user clicks the “Add” button on a product card. Receives the product that was selected. |
onSessionComplete | (summary: SessionSummary) => void | Fired when a response completes with a session summary, providing the current cart state. |
onError | (error: WidgetError) => void | Fired on any error — server-side or client-side. See Error Codes. |
onConnect | () => void | Fired when the WebSocket connection is authenticated and ready. |
onDisconnect | () => void | Fired when the WebSocket connection is closed (intentional or unexpected). |
ThemeConfig
The theme property accepts a ThemeConfig object:
| Property | Type | Default | Description |
|---|
primaryColor | string | '#2D8A4E' | Primary brand color. Applied to the toggle button, header, send button, links, and active states. |
fontFamily | string | "'Inter', system-ui, -apple-system, sans-serif" | Font stack for all widget text. |
borderRadius | string | '0px' | Base border radius for the chat panel, cards, and buttons. Use '12px' for rounded, '0px' for sharp corners. |
mode | 'light' | 'dark' | 'auto' | 'light' | Color scheme. 'auto' follows prefers-color-scheme. |
currency | string | undefined | Currency symbol displayed next to prices (e.g., '$', 'EUR'). |
Full Example
import { VIZOCHOKWidget } from '@vizochok/widget';
import type {
CartChangedEvent,
ProductItem,
SessionSummary,
WidgetError,
} from '@vizochok/widget';
const widget = new VIZOCHOKWidget({
// Required
apiKey: 'pk_live_abc123',
storeId: 'my-grocery-store',
// Identity & locale
userId: 'user_42',
language: 'uk',
apiBase: 'https://api.vizochok.com',
// Appearance
position: 'bottom-right',
botName: 'Мій помічник',
botAvatar: 'https://cdn.example.com/bot-avatar.png',
placeholder: 'Що шукаєте?',
welcomeMessage: 'Привіт! Я допоможу зі списком покупок.',
// Theme
theme: {
primaryColor: '#1a73e8',
fontFamily: "'Roboto', sans-serif",
borderRadius: '12px',
mode: 'auto',
currency: '$',
},
// Callbacks
onCartChanged: (cart: CartChangedEvent) => {
console.log('Cart updated:', cart.action, cart.items);
updateStoreCart(cart.items, cart.total);
},
onProductClick: (product: ProductItem) => {
console.log('Product selected:', product.sku);
},
onSessionComplete: (summary: SessionSummary) => {
console.log('Session summary:', summary.item_count, 'items');
},
onError: (error: WidgetError) => {
console.error('Widget error:', error.code, error.message);
},
onConnect: () => {
console.log('Connected to VIZOCHOK');
},
onDisconnect: () => {
console.log('Disconnected from VIZOCHOK');
},
});
widget.mount();
Public Methods
After creating the widget instance, use these methods to control it:
| Method | Description |
|---|
mount(target?: HTMLElement, options?: MountOptions) | Mounts the widget into the DOM. Defaults to document.body. Pass { inline: true } in options for embedded mode. |
unmount() | Removes the widget from the DOM and disconnects WebSocket. Preserves session in sessionStorage. |
open() | Opens the chat panel programmatically. |
close() | Closes the chat panel programmatically. |
toggle() | Toggles the chat panel open/closed. |
newChat() | Clears chat history and starts a new conversation. |
setMode(mode: 'inline' | 'floating', target?: HTMLElement) | Switches between inline and floating mode without destroying the WebSocket connection or chat state. |
destroy() | Fully destroys the widget — unmounts, clears state, and removes session data from sessionStorage. |
MountOptions
| Property | Type | Default | Description |
|---|
inline | boolean | false | When true, renders the widget inline (fills container) instead of as a floating panel. |
Session Persistence
The widget automatically persists chat history and conversation state to sessionStorage under the key vz-session-{storeId}. This means:
- Refreshing the page restores the previous conversation
- The
conversationId is preserved across page navigations
- Cart state is restored on reconnect via the
session_restored server message
- Calling
destroy() clears stored session data
- Calling
newChat() clears stored session data and resets the conversation
Session data is stored per-tab using sessionStorage, not localStorage. Opening a new tab starts a fresh session.