@cliniq360/eigi-widget
v1.2.3
Published
Embeddable AI assistant widget with voice, chat, and screen sharing capabilities
Readme
@cliniq360/eigi-widget
Embeddable AI assistant widget with voice, chat, and screen sharing capabilities. Built with React, Web Components, and powered by Pipecat.ai.
✨ Features
- 💬 Text Chat: Stream responses from your AI agent with real-time updates
- 🎙️ Voice Calls: Real-time voice conversation with Daily.co WebRTC integration
- 🖥️ Screen Share: Share your screen during calls (configurable)
- 📝 Real-time Transcripts: See live conversation transcripts during voice calls
- 🎨 Custom Themes: Fully customizable colors, fonts, and appearance via CSS variables
- 🛡️ Shadow DOM: Complete style isolation - no CSS conflicts with your site
- 🪶 Lightweight: Single ~290KB (gzipped) bundle with everything included
- 📱 Responsive: Adapts to mobile, tablet, and desktop screens
- ♿ Accessible: ARIA labels and keyboard navigation support
🚀 Quick Start
Using unpkg CDN (Recommended)
Add these two lines to your HTML:
<!-- The widget element -->
<eigi-widget agent-id="YOUR_AGENT_ID"></eigi-widget>
<!-- The widget script -->
<script src="https://unpkg.com/@cliniq360/eigi-widget@latest/dist/eigi-widget.js"></script>That's it! The widget will appear on your page with the configured placement.
Using jsdelivr CDN
<eigi-widget agent-id="YOUR_AGENT_ID"></eigi-widget>
<script src="https://cdn.jsdelivr.net/npm/@cliniq360/eigi-widget@latest/dist/eigi-widget.js"></script>Using npm
npm install @cliniq360/eigi-widgetThen in your JavaScript/TypeScript:
import "@cliniq360/eigi-widget";
// Now you can use <eigi-widget> in your HTMLOr with React/Vue/Angular:
// In your component
function MyPage() {
return (
<div>
<eigi-widget agent-id="YOUR_AGENT_ID" />
</div>
);
}📖 Usage
Basic Usage
<eigi-widget agent-id="68ee2e20e6ce6507cd24d920"></eigi-widget>With Metadata
Pass additional metadata to your agent for personalization:
<eigi-widget
agent-id="68ee2e20e6ce6507cd24d920"
metadata='{"user_id": "123", "source": "website", "plan": "premium", "name": "John Doe"}'
></eigi-widget>The metadata is sent with every API request to your agent.
Multiple Widgets
You can embed multiple widgets on the same page (e.g., different agents for sales, support):
<!-- Sales Agent -->
<eigi-widget
agent-id="sales-agent-id"
metadata='{"department": "sales"}'
></eigi-widget>
<!-- Support Agent -->
<eigi-widget
agent-id="support-agent-id"
metadata='{"department": "support"}'
></eigi-widget>Each widget runs independently with its own Shadow DOM isolation.
⚙️ Attributes
| Attribute | Type | Required | Description |
| ---------- | ------ | -------- | ---------------------------------------------------------- |
| agent-id | string | ✅ Yes | Your agent ID from CliniQ360 platform |
| metadata | string | ❌ No | JSON string with additional metadata to pass to your agent |
🎨 Widget Configuration
The widget appearance and behavior are configured through your CliniQ360 agent dashboard:
Appearance
- Theme Colors: Primary, secondary, accent colors with automatic shade generation
- Typography: Custom fonts, sizes, and weights
- Placement: Bottom-right, bottom-left, top-right, top-left
- Variant: Compact, Medium, Expanded views
- Border Radius: Customize rounded corners
Features
- Chat: Enable/disable text messaging
- Voice Calls: Real-time voice with Daily.co WebRTC
- Screen Share: Allow users to share their screen
- Real-time Transcripts: Show live conversation text during calls
- Send Text on Call: Allow text messages during voice calls
- Mute Button: Show/hide microphone toggle
- Auto-expand: Widget behavior on page load
Avatar
- Type: Gradient orb or custom image
- Custom Image: Upload your brand's avatar/logo
- Gradient Colors: Two-color gradient for orb animation
Behavior
- Expanded Behavior: Start expanded, always collapsed, or user-controlled
- Idle Prompt: Customize the call-to-action message
- Message Box Size: Compact, Medium, or Expanded
📦 Bundle Size
The widget is optimized for production:
- Bundled Size: ~6.5MB (minified, includes all dependencies)
- Gzipped: ~2.9MB (actual download size)
- Includes: React 19, Pipecat.ai client, Daily.co SDK, all UI components, Tailwind CSS, fonts
- No External Dependencies: Everything bundled in single file
🔧 Browser Support
- ✅ Chrome/Edge 90+ (Chromium)
- ✅ Firefox 88+
- ✅ Safari 14+
- ✅ Modern mobile browsers (iOS Safari, Chrome Mobile)
- ✅ Supports Shadow DOM and CSS Custom Properties
Required Browser Features:
- Shadow DOM (for style isolation)
- CSS Custom Properties (for theming)
- WebRTC (for voice calls)
- Fetch API (for agent communication)
🏗️ Architecture
Web Components + Shadow DOM
The widget uses native Web Components with Shadow DOM for complete CSS isolation:
class EigiWidgetElement extends HTMLElement {
connectedCallback() {
// Create Shadow DOM - prevents CSS conflicts
const shadow = this.attachShadow({ mode: "open" });
// Inject styles using Constructable Stylesheets (modern approach)
const sheet = new CSSStyleSheet();
sheet.replaceSync(css);
shadow.adoptedStyleSheets = [sheet];
// Mount React app inside Shadow DOM
const root = createRoot(shadow);
root.render(<EigiWidget />);
}
}
customElements.define("eigi-widget", EigiWidgetElement);Key Benefits:
- ✅ No CSS conflicts with your site
- ✅ Widget styles completely isolated
- ✅ Your site styles don't affect the widget
- ✅ Widget can be styled independently via CSS variables
Theming System
The widget uses CSS Custom Properties for dynamic theming:
/* Base theme injected in Shadow DOM */
:host,
* {
--widget-primary-color: #3b82f6;
--widget-background: #ffffff;
--widget-text-primary: #0f172a;
/* ... 100+ CSS variables */
}
/* Components use these variables */
.button {
background: var(--widget-primary-color);
color: var(--widget-primary-foreground);
}Why :host, * selector?
- In Shadow DOM,
:rootrefers to the document root (outside Shadow DOM) :hosttargets the shadow host element (the<eigi-widget>itself)- Combined
:host, *ensures variables are available everywhere in Shadow DOM
💻 Development
Building from Source
# Clone the repository
git clone https://github.com/CliniQ360/eigi-widget.git
cd eigi-widget
# Install dependencies
npm install
# Development mode (localhost:5174)
npm run dev
# Build for production
npm run build
# The output will be in dist/eigi-widget.jsProject Structure
eigi-widget/
├── src/
│ ├── components/ # React components
│ │ ├── widget/ # Main widget components
│ │ ├── ui/ # Reusable UI components
│ │ └── orb/ # Avatar orb animation
│ ├── hooks/ # React hooks
│ │ ├── useCallState.js
│ │ ├── useChatMessages.js
│ │ └── useTheme.js
│ ├── lib/ # Utilities
│ │ ├── theme-utils.js # Theme generation
│ │ └── theme-color-utils.js # Color transformations
│ ├── services/ # API and logger
│ ├── store/ # Zustand state management
│ ├── widget.jsx # Web Component entry point
│ └── App.jsx # Development preview
├── dist/ # Build output (git-ignored)
│ └── eigi-widget.js # Production bundle
└── Documentation/ # Technical docsLocal Development
The App.jsx file provides a development environment with a mock widget element:
// Simulates production Shadow DOM in development
class MockWidgetElement {
constructor(containerRef) {
this.containerRef = containerRef;
}
injectThemeCSS(css) {
// Injects theme CSS for local testing
}
}This allows you to:
- Test the widget locally without publishing
- See changes in real-time with hot reload
- Debug theme CSS injection
- Verify Shadow DOM behavior
Building and Testing
# Build the widget
npm run build
# Test locally with production build
# Create an HTML file:
cat > test.html << 'EOF'
<!DOCTYPE html>
<html>
<head><title>Widget Test</title></head>
<body>
<h1>Testing Widget</h1>
<eigi-widget agent-id="YOUR_AGENT_ID"></eigi-widget>
<script src="./dist/eigi-widget.js"></script>
</body>
</html>
EOF
# Open in browser
open test.html📤 Publishing
Prerequisites
- Update version in
package.json - Build the widget:
npm run build - Test the production bundle locally
- Ensure you're logged in to npm:
npm login
Publishing to npm
# Bump version (patch/minor/major)
npm version patch # 1.1.5 -> 1.1.6
# Build and publish (prepublishOnly runs automatically)
npm publish --access publicThe prepublishOnly script ensures the widget is always built before publishing.
What Gets Published
From package.json:
{
"files": ["dist", "README.md"]
}Only these files are included in the npm package:
dist/eigi-widget.js- Production bundleREADME.md- Documentation
Not included (stays in source control only):
src/- Source codenode_modules/- Dependencies- Development files
🔍 Troubleshooting
Widget Not Appearing
- Check agent-id: Ensure it's a valid agent ID from your dashboard
- Check console: Look for error messages in browser DevTools
- Check script loading: Verify the script URL is accessible
- Try a different CDN: Switch between unpkg and jsdelivr
Styles Not Applying
The widget uses Shadow DOM - styles are completely isolated:
- ✅ Correct: Widget manages its own styles via CSS variables
- ❌ Won't Work: External CSS cannot style widget internals
- ℹ️ To Customize: Configure theme in CliniQ360 dashboard
Voice Call Issues
- Microphone Permission: User must grant mic access
- HTTPS Required: Daily.co requires secure context
- Browser Support: Check WebRTC compatibility
- Network: Ensure firewall allows WebRTC connections
Build Errors
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install
# Clear Vite cache
rm -rf .vite node_modules/.vite
# Rebuild
npm run build🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Development Workflow
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes
- Test locally:
npm run dev - Build:
npm run build - Commit:
git commit -am 'Add new feature' - Push:
git push origin feature/my-feature - Create a Pull Request
� Documentation
Detailed technical documentation is available in the /Documentation folder:
- Implementation Summary - High-level overview
- Shadow DOM Implementation - CSS isolation details
- Widget Working - Component architecture
- Development Learnings - Challenges and solutions
- Publishing Guide - npm publishing workflow
�📄 License
MIT © CliniQ360
🔗 Links
💡 Support
For support, email [email protected] or visit our documentation.
Made with ❤️ by CliniQ360
