npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pindai-ai/chat-widget

v2.0.3

Published

Modern, accessible chat widget for Pindai.ai

Readme

Pindai Chat Widget

Modern, accessible chat widget for Pindai.ai - AI-powered document extraction for Indonesian enterprises

npm version npm downloads License: MIT jsDelivr hits

🚀 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-widget

Via 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 @2 automatically gives you the latest 2.x.x version with bug fixes and improvements. Use @2.0.1 if 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:

  1. Import the workflow from pindai-chat-workflow.json
  2. Add your OpenAI API key to the "OpenAI Chat Model" node
  3. Activate the workflow
  4. 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             # Documentation

Build Commands

# Development server with hot reload
npm run dev

# Production build
npm run build

# Preview production build
npm run preview

Testing

  1. Start dev server:

    npm run dev
  2. Open browser: http://localhost:5173

  3. Test 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)
  4. Accessibility audit:

    • Open DevTools > Lighthouse
    • Run Accessibility audit
    • Should score 100

📝 Changelog

Version 2.0.1 (2026-02-06)

Updates:

  • Vendor-agnostic API: Changed n8nUrl to webhookUrl parameter
  • 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 N8nChatWidget to PindaiChatWidget
  • 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:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

MIT © Pindai.ai


🔗 Links


🆘 Support


🙏 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