chat-snail-sdk
v1.2.1
Published
Modern AI Chatbot Widget SDK with Shadow DOM isolation and Dify.ai integration
Maintainers
Readme
AI Chat Widget SDK 🤖
A modern, customizable AI chatbot widget SDK with Shadow DOM isolation. Perfect for integrating AI-powered chat functionality into any website while maintaining complete style isolation and security.
✨ Features
- 🎨 Customizable Themes - Light/Dark mode with smooth transitions
- 🌍 Multi-language Support - Built-in support for 6 languages (EN, ZH, ES, FR, JA)
- 🔒 Shadow DOM Isolation - Complete style isolation from host page
- 📱 Responsive Design - Works seamlessly on desktop and mobile
- 🎯 Draggable Interface - Move the chat window anywhere on screen
- 💾 Persistent Conversations - LocalStorage integration for chat history
- 📸 Image Upload Support - Send images with messages (PNG, JPG, WebP, GIF)
- ⚡ Lightweight - Less than 50KB minified
- 🔐 Security First - Built-in API key security warnings
- 🎬 Smooth Animations - Professional transitions and effects
- ♿ Accessibility - ARIA labels and keyboard navigation
🚀 Quick Start
CDN Installation
<script src="https://unpkg.com/ai-chat-widget-sdk/dist/widget.min.js"></script>
<script>
const widget = new AIChatWidget({
welcomeMessage: 'Hello! How can I help you today?'
}).init();
</script>Dify.ai Integration
const widget = new AIChatWidget({
apiProvider: 'dify',
apiKey: 'app-your-dify-api-key',
difyConfig: {
baseUrl: 'https://api.dify.ai',
streaming: true
}
}).init();NPM Installation
npm install ai-chat-widget-sdkimport AIChatWidget from 'ai-chat-widget-sdk';
const widget = new AIChatWidget({
theme: 'dark',
language: 'en',
apiEndpoint: 'https://your-api.com/chat'
}).init();📋 Configuration Options
const widget = new AIChatWidget({
// Appearance
position: 'bottom-right', // 'bottom-right', 'bottom-left', 'top-right', 'top-left'
theme: 'light', // 'light' or 'dark'
primaryColor: '#007bff', // Custom primary color
width: 380, // Chat window width
height: 600, // Chat window height
zIndex: 9999, // z-index for stacking
// Content
title: 'AI Assistant', // Chat window title
subtitle: 'Powered by AI', // Subtitle text
welcomeMessage: 'Hello!', // Initial bot message
placeholder: 'Type here...', // Input placeholder
buttonIcon: '💬', // Floating button icon
userAvatar: '👤', // User message avatar
botAvatar: '🤖', // Bot message avatar
// Behavior
language: 'en', // 'en', 'zh', 'es', 'fr', 'ja'
enableDrag: true, // Allow dragging chat window
autoOpen: false, // Auto-open on load
autoOpenDelay: 3000, // Delay before auto-open (ms)
persistConversation: true, // Save chat history
maxMessageLength: 1000, // Max input length
// API Configuration
apiEndpoint: null, // Your chat API endpoint
apiKey: null, // API key (⚠️ Use server-side!)
apiProvider: 'custom', // 'custom' or 'dify'
difyConfig: { // Dify.ai specific config
baseUrl: 'https://api.dify.ai',
user: null, // User identifier
streaming: true // Enable streaming responses
}
// Advanced Features
enableFileUpload: false, // Enable file attachments
enableVoiceInput: false, // Enable voice input
animations: {
enabled: true,
duration: 300
},
sounds: {
enabled: false,
newMessage: null, // Sound file URL
sendMessage: null // Sound file URL
}
});🔌 API Methods
// Core Methods
widget.init(); // Initialize the widget
widget.destroy(); // Remove widget from DOM
widget.toggle(); // Toggle open/close
widget.open(); // Open chat window
widget.close(); // Close chat window
// Messaging
widget.sendMessage('Hello!'); // Send a message programmatically
// Customization
widget.setTheme('dark'); // Change theme
widget.setLanguage('zh'); // Change language
// Events
widget.on('message', callback); // Listen for events
widget.off('message', callback); // Remove listener📡 Events
widget.on('init', () => {
console.log('Widget initialized');
});
widget.on('open', () => {
console.log('Chat opened');
});
widget.on('close', () => {
console.log('Chat closed');
});
widget.on('message', (data) => {
console.log('User message:', data);
// { type: 'user', content: 'Hello', timestamp: '...' }
});
widget.on('response', (data) => {
console.log('Bot response:', data);
// { type: 'bot', content: 'Hi there!', timestamp: '...' }
});
widget.on('error', (error) => {
console.error('Error occurred:', error);
});
widget.on('theme-change', (theme) => {
console.log('Theme changed to:', theme);
});
widget.on('language-change', (lang) => {
console.log('Language changed to:', lang);
});🔐 Security Best Practices
⚠️ API Key Security
Never expose API keys in frontend code! The SDK will warn you if it detects an API key without a server endpoint.
❌ Bad (Insecure)
const widget = new AIChatWidget({
apiKey: 'sk-abc123...' // NEVER DO THIS!
});✅ Good (Secure)
// Frontend
const widget = new AIChatWidget({
apiEndpoint: 'https://your-server.com/api/chat'
// No API key here!
});
// Backend (Node.js example)
app.post('/api/chat', async (req, res) => {
const response = await openai.chat({
apiKey: process.env.OPENAI_API_KEY, // Secure!
message: req.body.message
});
res.json(response);
});🎨 Styling & Theming
The widget uses Shadow DOM for complete style isolation. You can customize the appearance through:
- Configuration options - Set colors, sizes, and positions
- Theme presets - Light and dark themes included
- Custom CSS variables - Override default styles
// Custom theme example
const widget = new AIChatWidget({
primaryColor: '#ff6b6b',
theme: 'dark',
width: 400,
height: 550
});🌍 Internationalization
Built-in support for multiple languages:
- 🇬🇧 English (en)
- 🇨🇳 Chinese (zh)
- 🇪🇸 Spanish (es)
- 🇫🇷 French (fr)
- 🇯🇵 Japanese (ja)
// Change language dynamically
widget.setLanguage('zh');
// Or set during initialization
const widget = new AIChatWidget({
language: 'es'
});📱 Mobile Support
The widget is fully responsive and adapts to mobile screens:
- Auto-fullscreen on small devices
- Touch-friendly interface
- Optimized keyboard handling
- Gesture support for dragging
🛠️ Development
Setup
# Clone the repository
git clone https://github.com/yourusername/ai-chat-widget-sdk.git
# Install dependencies
npm install
# Start development server
npm run dev
# Build for production
npm run buildProject Structure
ai-widget-sdk/
├── src/
│ ├── index.js # Main entry point
│ ├── core/
│ │ └── WidgetCore.js # Core widget logic
│ ├── components/
│ │ ├── ChatWindow.js # Chat window component
│ │ ├── FloatingButton.js # Floating button
│ │ ├── MessageList.js # Message list
│ │ └── InputArea.js # Input area
│ ├── utils/
│ │ ├── EventEmitter.js # Event system
│ │ ├── StorageManager.js # LocalStorage handler
│ │ ├── DragManager.js # Drag functionality
│ │ └── i18n.js # Translations
│ └── styles/
│ └── main.css # Global styles
├── dist/
│ └── widget.min.js # Production build
├── examples/
│ └── index.html # Demo page
└── package.json🤝 Browser Support
- Chrome 60+
- Firefox 55+
- Safari 11+
- Edge 79+
- Mobile browsers (iOS Safari, Chrome Mobile)
📄 License
MIT License - feel free to use in personal and commercial projects.
🙏 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
💡 Examples
Basic Implementation
<!DOCTYPE html>
<html>
<head>
<title>My Website</title>
</head>
<body>
<h1>Welcome to my site!</h1>
<!-- AI Chat Widget -->
<script src="https://unpkg.com/ai-chat-widget-sdk/dist/widget.min.js"></script>
<script>
const widget = new AIChatWidget({
welcomeMessage: 'Hi! Need help navigating our site?',
apiEndpoint: '/api/chat'
}).init();
</script>
</body>
</html>React Integration
import { useEffect, useRef } from 'react';
import AIChatWidget from 'ai-chat-widget-sdk';
function App() {
const widgetRef = useRef(null);
useEffect(() => {
widgetRef.current = new AIChatWidget({
theme: 'dark',
language: 'en'
}).init();
return () => {
widgetRef.current?.destroy();
};
}, []);
return <div>Your React App</div>;
}Vue Integration
<template>
<div>Your Vue App</div>
</template>
<script>
import AIChatWidget from 'ai-chat-widget-sdk';
export default {
mounted() {
this.widget = new AIChatWidget({
theme: 'light'
}).init();
},
beforeDestroy() {
this.widget?.destroy();
}
}
</script>🔗 Links
📞 Support
For issues and questions:
- Open an issue on GitHub
- Email: [email protected]
Made with ❤️ by Your Team
