Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.blackbox.dasha.ai/llms.txt

Use this file to discover all available pages before exploring further.

Make the widget match your brand. Customize colors, themes, and position using CSS variables. Control behavior with the JavaScript API. What you’ll learn: Theme and position options, feature gating, JavaScript API, event handling, CSS variables, and mobile optimization.

Built-in customization

<!-- Light theme -->
<blackbox-agent theme="light"></blackbox-agent>

<!-- Dark theme -->
<blackbox-agent theme="dark"></blackbox-agent>
ThemeBest for
lightLight-colored websites, minimalist designs
darkDark-mode sites, tech products, dashboards
<!-- Bottom positions (recommended) -->
<blackbox-agent position="bottom-right"></blackbox-agent>
<blackbox-agent position="bottom-left"></blackbox-agent>
<blackbox-agent position="bottom-center"></blackbox-agent>

<!-- Top positions -->
<blackbox-agent position="top-right"></blackbox-agent>
<blackbox-agent position="top-left"></blackbox-agent>
<blackbox-agent position="top-center"></blackbox-agent>
bottom-right is most familiar to users—it’s where chat widgets typically appear.

Feature gating

Control which features appear in the widget UI.
<blackbox-agent
  skip-discovery
  data-config='{
    "features": ["AllowWebCall", "AllowWebChat"],
    "enableFeatureGating": true,
    "uiGatingMode": "hide"
  }'
></blackbox-agent>

Gating modes

ModeBehavior
hideCompletely remove disabled features
disableShow features grayed out

Common configurations

{
  "features": ["AllowWebCall"],
  "enableFeatureGating": true,
  "uiGatingMode": "hide"
}

JavaScript API

Control the widget programmatically for advanced integrations.
const widget = document.querySelector('blackbox-agent');
// Open widget
widget.open();

// Close widget
widget.close();

// Toggle
widget.toggle();
// Open after scroll
window.addEventListener('scroll', () => {
  if (window.scrollY > 500) widget.open();
});

// Open on button click
document.getElementById('help-btn').addEventListener('click', () => {
  widget.open();
});

// Open for new visitors after delay
if (!localStorage.getItem('returning')) {
  setTimeout(() => widget.open(), 5000);
  localStorage.setItem('returning', 'true');
}

Event handling

React to widget events in your application.
const widget = document.querySelector('blackbox-agent');

// Widget opened
widget.addEventListener('widget-opened', (e) => {
  console.log('Widget opened');
});

// Widget closed
widget.addEventListener('widget-closed', (e) => {
  console.log('Widget closed');
});

// Call started
widget.addEventListener('call-started', (e) => {
  console.log('Call ID:', e.detail.callId);
  console.log('Type:', e.detail.callType); // 'voice' or 'chat'
});

// Call ended
widget.addEventListener('call-ended', (e) => {
  console.log('Duration:', e.detail.duration);
  console.log('Status:', e.detail.status);
  showFeedbackForm();
});

// Error occurred
widget.addEventListener('widget-error', (e) => {
  console.error('Error:', e.detail.error);
});

// Transcript update (if SendTranscriptForAudioCall enabled)
widget.addEventListener('transcript-update', (e) => {
  console.log(`${e.detail.speaker}: ${e.detail.text}`);
});

// Tool executed (if SendToolCallLogs enabled)
widget.addEventListener('tool-executed', (e) => {
  console.log('Tool:', e.detail.toolName);
  console.log('Result:', e.detail.result);
});
When SendCallResult is enabled:
widget.addEventListener('call-result', (e) => {
  const result = e.detail;

  if (result.data.appointment) {
    // Agent scheduled an appointment
    addToCalendar(result.data.appointment);
  }

  if (result.data.lead) {
    // Agent captured lead info
    sendToCRM(result.data.lead);
  }
});

CSS customization

Override CSS variables for custom styling.
CSS variable names may change in future versions. Test after widget updates.
blackbox-agent {
  /* Primary brand color */
  --widget-primary-color: #4F46E5;

  /* Backgrounds */
  --widget-background: #FFFFFF;
  --widget-header-background: #F9FAFB;

  /* Text */
  --widget-text-primary: #111827;
  --widget-text-secondary: #6B7280;

  /* Borders */
  --widget-border-color: #E5E7EB;
  --widget-border-radius: 12px;

  /* Shadow */
  --widget-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);

  /* Buttons */
  --widget-button-background: #4F46E5;
  --widget-button-text: #FFFFFF;
  --widget-button-hover: #4338CA;

  /* Size */
  --widget-width: 380px;
  --widget-height: 600px;

  /* Position offset */
  --widget-offset-x: 20px;
  --widget-offset-y: 20px;
}

Brand examples

blackbox-agent {
  --widget-primary-color: #0066CC;
  --widget-button-background: #0066CC;
  --widget-button-hover: #0052A3;
  --widget-border-radius: 8px;
}
/* Default desktop */
blackbox-agent {
  --widget-width: 380px;
  --widget-height: 600px;
}

/* Full screen on mobile */
@media (max-width: 768px) {
  blackbox-agent {
    --widget-width: 100vw;
    --widget-height: 100vh;
    --widget-offset-x: 0;
    --widget-offset-y: 0;
  }
}

Match user preferences or site theme:
const widget = document.querySelector('blackbox-agent');

// Follow system preference
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)');
widget.setAttribute('theme', prefersDark.matches ? 'dark' : 'light');

// Listen for changes
prefersDark.addEventListener('change', (e) => {
  widget.setAttribute('theme', e.matches ? 'dark' : 'light');
});

Mobile optimization

The widget automatically adapts to mobile:
  • Full-screen when expanded
  • Touch-optimized buttons
  • Prominent microphone button
  • Swipe gestures to close

Mobile best practices

DoAvoid
Use bottom positionsAuto-open on load
Prefer voice over typingUse top-center (blocks nav)
Test on actual devicesMake minimized button too small
Allow easy dismissalRequire extensive typing
function isMobile() {
  return /Android|iPhone|iPad|iPod/i.test(navigator.userAgent) ||
         window.innerWidth < 768;
}

if (isMobile()) {
  const widget = document.querySelector('blackbox-agent');
  widget.setAttribute('position', 'bottom-center');
}

Use case examples

<style>
  blackbox-agent.support {
    --widget-primary-color: #2563EB;
    --widget-border-radius: 8px;
  }
</style>

<blackbox-agent
  class="support"
  theme="light"
  position="bottom-right"
  data-config='{"features":["AllowWebCall","AllowWebChat"]}'
></blackbox-agent>

<script>
  // Open if user is idle
  let idle = 0;
  setInterval(() => {
    if (++idle > 30) {
      document.querySelector('blackbox-agent').open();
      idle = 0;
    }
  }, 1000);
  document.addEventListener('mousemove', () => idle = 0);
</script>
<blackbox-agent
  theme="dark"
  position="bottom-center"
  data-config='{"features":["AllowWebCall","SendCallResult"]}'
></blackbox-agent>

<script>
  const widget = document.querySelector('blackbox-agent');

  // Open after reading content
  setTimeout(() => widget.open(), 45000);

  // Capture lead data
  widget.addEventListener('call-result', (e) => {
    if (e.detail.data?.lead) {
      fetch('/api/leads', {
        method: 'POST',
        body: JSON.stringify(e.detail.data.lead)
      });
    }
  });
</script>

Accessibility

The widget supports accessibility features:
FeatureSupport
Keyboard navigationTab to focus, Enter to open
Screen readersARIA labels on controls
Focus managementTrapped when open
Escape keyCloses widget
High contrastSupported
Enable SendTranscriptForAudioCall to provide text alternatives for voice calls.

What’s next

Widget Configuration

Configure security and features

Web Widget Embedding

Installation guides

Webhooks

Handle events server-side

Call History

Track widget performance