Botovis

Widget

Chat widget configuration, theming, JavaScript API, and framework integration

The Botovis widget is a zero-dependency Web Component built with Shadow DOM. It provides a complete chat interface with streaming support, markdown rendering, conversation history, and full theming capabilities.

Adding the Widget

Blade Directive

The simplest way to add the widget in Laravel:

@botovisWidget

This renders the widget with default settings. You can customize with an options array:

@botovisWidget([
    'theme' => 'dark',
    'lang' => 'en',
    'position' => 'bottom-left',
    'streaming' => true,
])

HTML Attributes

All widget behavior can be controlled via HTML attributes:

<botovis-chat
    endpoint="/botovis"
    theme="dark"
    lang="en"
    position="bottom-right"
    title="Database Assistant"
    placeholder="Type your question..."
    streaming="true"
    csrf-token="your-csrf-token"
    sounds="true"
></botovis-chat>
AttributeDefaultDescription
endpoint/botovisBase URL for the Botovis API
themeautoWidget theme: light, dark, or auto (follows system preference)
langenUI language: en or tr
positionbottom-rightWidget position: bottom-right or bottom-left
titleBotovisChat window title
placeholderType a message...Input field placeholder text
streamingtrueEnable SSE streaming for real-time responses
csrf-tokenCSRF token for API requests (auto-detected from meta tag in Laravel)
soundsEnable notification sounds for incoming messages

JavaScript API

The widget exposes a JavaScript API for programmatic control:

const widget = document.querySelector('botovis-chat');

// Open / close / toggle the chat window
widget.open();
widget.close();
widget.toggle();

// Send a message programmatically
widget.send('How many active users do we have?');

// Cancel an ongoing stream
widget.cancelStream();

Events

The widget dispatches custom events you can listen to:

const widget = document.querySelector('botovis-chat');

widget.addEventListener('botovis:open', () => {
    console.log('Chat opened');
});

widget.addEventListener('botovis:close', () => {
    console.log('Chat closed');
});

widget.addEventListener('botovis:step', (e) => {
    console.log('Agent step:', e.detail);
});

Keyboard Shortcuts

ShortcutAction
Ctrl+K / Cmd+KToggle the chat window
EscapeClose the chat window (or close history panel if open)
EnterSend message
Shift+EnterNew line in the input

Theming

The widget uses CSS custom properties (variables) for complete visual customization. Since it uses Shadow DOM, styles don't leak in or out.

CSS Variables

Override these variables on the botovis-chat element:

botovis-chat {
    /* Primary Colors */
    --bv-primary: #6366f1;
    --bv-primary-hover: #4f46e5;
    --bv-primary-light: #eef2ff;
    --bv-primary-text: #ffffff;

    /* Accent */
    --bv-accent: #0ea5e9;
    --bv-accent-light: #e0f2fe;

    /* Backgrounds */
    --bv-bg: #ffffff;
    --bv-bg-elevated: #ffffff;
    --bv-surface: #f8fafc;
    --bv-surface-hover: #f1f5f9;

    /* Text */
    --bv-text: #0f172a;
    --bv-text-secondary: #475569;
    --bv-text-muted: #94a3b8;

    /* Borders */
    --bv-border: #e2e8f0;
    --bv-border-light: #f1f5f9;

    /* Status Colors */
    --bv-success: #059669;
    --bv-success-bg: #ecfdf5;
    --bv-error: #dc2626;
    --bv-error-bg: #fef2f2;
    --bv-warning: #d97706;
    --bv-warning-bg: #fffbeb;
    --bv-info: #0284c7;
    --bv-info-bg: #f0f9ff;

    /* Dimensions */
    --bv-drawer-width: 420px;
    --bv-radius: 12px;
    --bv-radius-sm: 8px;
    --bv-radius-xs: 4px;

    /* Shadows */
    --bv-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
    --bv-shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.08);
}

Dark Theme Example

botovis-chat[theme="dark"] {
    --bv-bg: #0f172a;
    --bv-bg-elevated: #1e293b;
    --bv-surface: #1e293b;
    --bv-surface-hover: #334155;
    --bv-text: #f1f5f9;
    --bv-text-secondary: #94a3b8;
    --bv-text-muted: #64748b;
    --bv-border: #334155;
    --bv-border-light: #1e293b;
}

Widget Layout

The widget consists of these visual sections:

┌─────────────────────────────────┐
│  Header (title + subtitle)       │  ← Close button, theme toggle
├─────────────────────────────────┤
│                                  │
│  Message Area                    │  ← Scrollable chat history
│  ┌─────────────────────────┐    │
│  │ User message bubble     │    │
│  └─────────────────────────┘    │
│  ┌─────────────────────────┐    │
│  │ AI message bubble       │    │
│  │ (with markdown render)  │    │
│  │ ┌─ Step details ──────┐ │    │
│  │ │ 🔧 search_records   │ │    │
│  │ └─────────────────────┘ │    │
│  └─────────────────────────┘    │
│  ┌─────────────────────────┐    │
│  │ Confirmation card       │    │  ← Confirm / Reject buttons
│  └─────────────────────────┘    │
│                                  │
├─────────────────────────────────┤
│  Input area                      │  ← Auto-resizing textarea
│  [Type a message...]     [Send]  │
└─────────────────────────────────┘
                            [FAB]    ← Floating action button

Markdown Support

AI responses are rendered with full Markdown support:

  • Bold, italic, strikethrough
  • Headings (##, ###)
  • Ordered and unordered lists
  • Code blocks with syntax highlighting
  • Tables
  • Links

Conversation History

When conversations are enabled in your configuration, the widget provides:

  • Save conversations — Current chat can be saved with a title
  • Load conversations — Previously saved chats can be resumed
  • Auto-title — Conversations are automatically titled based on the first message
  • Delete conversations — Users can manage their saved chats

The conversation list is accessible from the header menu.

Framework Integration

React Wrapper

import { useEffect, useRef } from 'react';

function BotovisWidget({ endpoint = '/botovis', theme = 'auto', lang = 'en' }) {
    const ref = useRef(null);

    useEffect(() => {
        // Import the widget script
        import('@botovis/widget');
    }, []);

    return (
        <botovis-chat
            ref={ref}
            endpoint={endpoint}
            theme={theme}
            lang={lang}
        />
    );
}

Vue 3 Wrapper

<template>
    <botovis-chat
        :endpoint="endpoint"
        :theme="theme"
        :lang="lang"
    />
</template>

<script setup>
import { onMounted } from 'vue';

defineProps({
    endpoint: { type: String, default: '/botovis' },
    theme: { type: String, default: 'auto' },
    lang: { type: String, default: 'en' },
});

onMounted(() => {
    import('@botovis/widget');
});
</script>

CDN Usage

You can load the widget directly from a CDN without any build tools:

<script src="https://unpkg.com/@botovis/widget/dist/botovis-widget.iife.js"></script>

<botovis-chat
    endpoint="https://your-app.com/botovis"
    theme="dark"
    lang="en"
></botovis-chat>

CORS

When using the CDN version with a different domain, make sure your Laravel app's CORS configuration allows requests from the widget's origin.

Internationalization (i18n)

The widget includes built-in translations for English and Turkish. Set the language with the lang attribute:

<botovis-chat lang="tr"></botovis-chat>

All UI strings (buttons, placeholders, error messages, confirmation dialogs) are translated. The widget includes 68 translation keys covering every user-facing string.

On this page