@pindai-ai/chat-widget
v2.0.3
Published
Modern, accessible chat widget for Pindai.ai
Maintainers
Readme
Pindai Chat Widget
Modern, accessible chat widget for Pindai.ai - AI-powered document extraction for Indonesian enterprises
🚀 Quick Start
<!-- Add this to your HTML -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat'
});
});
</script>✨ Features
- 🎨 Modern UI - HubSpot-quality design with smooth animations and Pindai.ai branding
- ♿ Accessible - WCAG 2.2 AA compliant with full keyboard navigation and screen reader support
- 📱 Mobile-First - Optimized responsive design for all devices
- 🌐 Bilingual - Indonesian (default) and English localization
- 📎 File Upload - Support for PDFs, images, and documents
- 💾 Persistent - Message history and state saved to localStorage
- 🔔 Notifications - Unread message badges and optional sound alerts
- ⚡ Quick Replies - Suggested responses for common questions
- 🔄 Retry Logic - Automatic retry with exponential backoff on network errors
- 📡 Offline Support - Graceful offline detection and user messaging
- ⌨️ Keyboard Nav - Full keyboard support (Tab, Enter, ESC)
- 🎯 Lightweight - Only ~12KB gzipped (JS + CSS)
- 🔧 Backend Agnostic - Works with n8n, Dify, custom APIs, or any HTTP endpoint
📦 Installation
Via npm
npm install @pindai-ai/chat-widgetVia CDN (jsDelivr)
Latest 2.x version (recommended):
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.css">
<script type="module"
src="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.js"></script>Specific version (2.0.1):
<link rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/@pindai-ai/[email protected]/dist/pindai-chat-widget.css">
<script type="module"
src="https://cdn.jsdelivr.net/npm/@pindai-ai/[email protected]/dist/pindai-chat-widget.js"></script>Using
@2automatically gives you the latest 2.x.x version with bug fixes and improvements. Use@2.0.1if you need a specific version.
Local Development
# Clone repository
git clone https://github.com/pindai-ai/pindai-chat-widget.git
cd pindai-chat-widget
# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build📖 Usage Examples
Complete HTML Example
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8">
<title>Your Website</title>
</head>
<body>
<h1>Welcome to My Website</h1>
<p>Your content here...</p>
<!-- Pindai Chat Widget -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.css">
<script type="module" src="https://cdn.jsdelivr.net/npm/@pindai-ai/chat-widget@2/dist/pindai-chat-widget.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat',
title: 'Customer Support',
locale: 'id' // 'id' for Indonesian, 'en' for English
});
});
</script>
</body>
</html>Using During Development
If the widget isn't on npm yet, use the GitHub CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/YOUR-USERNAME/pindai-chat-widget@main/dist/pindai-chat-widget.css">
<script type="module" src="https://cdn.jsdelivr.net/gh/YOUR-USERNAME/pindai-chat-widget@main/dist/pindai-chat-widget.js"></script>Replace YOUR-USERNAME with your GitHub username
⚙️ Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| Required |
| webhookUrl | string | - | Required. Your backend API endpoint (works with any service: n8n, Dify, custom API, etc.) |
| Display |
| mode | string | 'widget' | Display mode: 'widget' or 'fullscreen' |
| locale | string | 'id' | Language: 'id' (Indonesian) or 'en' (English) |
| title | string | Localized | Chat header title |
| initialMessage | string | Localized | First AI message |
| Branding |
| logoUrl | string | 'https://pindai.ai/logo.png' | Header logo URL |
| showLogo | boolean | true | Show/hide logo |
| launcherColor | string | '#0066FF' | Launcher button background color |
| launcherIconUrl | string | Default icon | Custom launcher icon URL |
| sendButtonColor | string | '#0066FF' | Send button background color |
| accentColor | string | '#00C896' | Accent color for UI elements |
| File Upload |
| enableFileUpload | boolean | true | Enable file attachments |
| allowedFileTypes | array | See below | Accepted MIME types |
| maxFileSize | number | 10485760 | Max file size in bytes (10MB default) |
| maxFiles | number | 5 | Max files per message |
| Features |
| enableNotifications | boolean | true | Show unread badges |
| enableSound | boolean | false | Play notification sound |
| enableHistory | boolean | true | Persist message history |
| maxHistoryItems | number | 50 | Max messages to store |
| showQuickReplies | boolean | true | Show quick reply buttons |
| quickReplies | array | Localized | Custom suggested responses |
| Technical |
| maxRetries | number | 3 | API retry attempts |
| retryDelay | number | 1000 | Retry delay in ms |
| requestTimeout | number | 30000 | Request timeout in ms (30s) |
| rateLimit | number | 5 | Messages per minute |
| rateLimitWindow | number | 60000 | Rate limit window in ms |
Default Allowed File Types
[
'image/jpeg', 'image/png', 'image/gif', 'image/webp',
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
]🔌 Backend API Format
Request (from Widget)
The widget sends a POST request with FormData containing:
{
"sessionId": "web-session-1234567890-0.123",
"message": "User message text",
"file0": File, // Optional: uploaded files
"file1": File, // Optional: multiple files supported
// ...
}Response (from Backend)
Your backend should respond with JSON:
{
"response": "AI response text"
}Example Backend Implementations
We provide a ready-to-use n8n workflow with AI chat memory!
Quick Setup:
- Import the workflow from
pindai-chat-workflow.json - Add your OpenAI API key to the "OpenAI Chat Model" node
- Activate the workflow
- Copy the webhook URL and use it in your widget
What's included:
- AI Agent with Indonesian system prompt
- Chat memory (remembers last 10 messages per session)
- Automatic response formatting
- Ready for production use
For detailed setup instructions, see N8N_WORKFLOW_GUIDE.md
Simple Test Workflow:
If you want to test without AI first, use pindai-chat-workflow-simple.json - no API keys needed!
const express = require('express');
const app = express();
app.post('/webhook/chat', express.json(), async (req, res) => {
const { sessionId, message } = req.body;
// Your AI logic here
const aiResponse = await processWithAI(message);
res.json({ response: aiResponse });
});from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhook/chat', methods=['POST'])
def chat():
data = request.get_json()
session_id = data.get('sessionId')
message = data.get('message')
# Your AI logic here
ai_response = process_with_ai(message)
return jsonify({'response': ai_response})🎨 Customization Examples
Custom Branding
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat',
locale: 'id',
title: 'Bantuan Pelanggan',
logoUrl: 'https://yourcompany.com/logo.png',
launcherColor: '#FF5733',
sendButtonColor: '#4CAF50',
accentColor: '#FFC107',
});Custom Quick Replies
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat',
quickReplies: [
'Cara membuat akun?',
'Lupa password',
'Hubungi customer service',
'Lihat demo produk'
],
});Fullscreen Mode (for dedicated chat pages)
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat',
mode: 'fullscreen', // Takes over entire page
title: 'Customer Support',
});Disable Features
window.PindaiChatWidget.init({
webhookUrl: 'https://your-backend.com/webhook/chat',
enableFileUpload: false, // Disable file uploads
enableHistory: false, // Don't save chat history
showQuickReplies: false, // Hide quick reply buttons
});♿ Accessibility
This widget meets WCAG 2.2 Level AA compliance:
✅ Full keyboard navigation (Tab, Enter, ESC) ✅ ARIA labels and landmarks ✅ Screen reader compatible ✅ 4.5:1 color contrast ratios ✅ Focus indicators ✅ Text resizable to 200% ✅ Touch targets ≥ 44×44px
Keyboard Shortcuts
| Key | Action |
|-----|--------|
| Tab | Navigate between elements |
| Enter | Send message / Activate button |
| ESC | Close widget |
| Space | Activate launcher |
🌐 Browser Support
| Browser | Version | |---------|---------| | Chrome/Edge | 90+ | | Firefox | 88+ | | Safari | 14+ | | iOS Safari | 14+ | | Android Chrome | 90+ |
🔧 Development
Project Structure
pindai-chat/
├── src/
│ ├── main.js # Core widget logic
│ ├── style.css # All styles
│ └── i18n.js # Internationalization
├── dist/ # Built assets
├── images/ # Demo assets
├── index.html # Demo page
├── vite.config.js # Build configuration
├── package.json # Package metadata
└── README.md # DocumentationBuild Commands
# Development server with hot reload
npm run dev
# Production build
npm run build
# Preview production build
npm run previewTesting
Start dev server:
npm run devOpen browser:
http://localhost:5173Test features:
- Click launcher to open chat
- Send messages
- Upload files (PDF, images)
- Test quick replies
- Try keyboard navigation (Tab, ESC)
- Test offline mode (DevTools > Network > Offline)
- Check mobile responsiveness (DevTools > Device Toolbar)
Accessibility audit:
- Open DevTools > Lighthouse
- Run Accessibility audit
- Should score 100
📝 Changelog
Version 2.0.1 (2026-02-06)
Updates:
- Vendor-agnostic API: Changed
n8nUrltowebhookUrlparameter - Added backward compatibility for
n8nUrl - Added "Powered by Pindai.ai" watermark in widget footer
- Updated documentation with n8n workflow examples
- Included ready-to-use n8n workflow JSON files
Version 2.0.0 (2026-02-05)
Major Changes:
- Complete UI/UX redesign with Pindai.ai branding
- Indonesian localization (default) with English support
- File upload capability (PDF, images, documents)
- WCAG 2.2 AA accessibility compliance
- Mobile-first responsive design
- Message history persistence
- Quick reply buttons
- Notification badges
- Enhanced error handling with retry logic
- Offline detection and user messaging
- Rate limiting
- Keyboard navigation (Tab, ESC)
Technical:
- Renamed from
N8nChatWidgettoPindaiChatWidget - Added i18n system
- CSS variables for theming
- FormData for file uploads
- localStorage for history/state
- Backward compatibility maintained
Breaking Changes:
- Default locale changed to Indonesian (
'id') - File uploads now use FormData instead of JSON
- Some CSS class names updated
Version 1.0.0
- Initial release
- Basic chat functionality
- n8n integration
🤝 Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT © Pindai.ai
🔗 Links
- npm Package: npmjs.com/package/@pindai-ai/chat-widget
- jsDelivr CDN: jsdelivr.com/package/npm/@pindai-ai/chat-widget
- GitHub Repository: github.com/pindai-ai/pindai-chat-widget
- Issues & Bugs: github.com/pindai-ai/pindai-chat-widget/issues
- Pindai.ai Website: pindai.ai
🆘 Support
- Documentation: N8N_WORKFLOW_GUIDE.md
- Issues: GitHub Issues
- Email: [email protected]
- Website: pindai.ai
🙏 Acknowledgments
- Inspired by HubSpot chat widget design patterns
- Built with modern web standards and accessibility best practices
- Designed for Indonesian enterprises
- Powered by Pindai.ai's AI document extraction technology
Made with ❤️ by Pindai.ai for Indonesian businesses
