sagegreytechnologies-nkiru-ai-chat-widget-webcomponent

Native Web Component chat widget with complete CSS isolation using Shadow DOM
1,532
Install
npm install sagegreytechnologies-nkiru-ai-chat-widget-webcomponent
Latest Version:2.6.0
License:MIT
Last Updated:Oct 1, 2026
Links: npm

🤖 AI Chat Widget - Web Component

A modern, customizable AI chat widget as a native Web Component with complete CSS isolation using Shadow DOM. Works with any framework or vanilla HTML - React, Vue.js, Angular, and more!

npm version TypeScript Web Components

✨ Features

  • 🎨 Fully Customizable - Colors, positioning, messages, and styling
  • 🔒 Complete CSS Isolation - Uses Shadow DOM for true style encapsulation
  • 🚀 Zero Dependencies - Pure vanilla JavaScript Web Component
  • 🌐 Universal Compatibility - Works with any framework or vanilla HTML
  • 📱 Responsive Design - Works perfectly on desktop and mobile
  • 🔄 Session Management - Automatic session restoration and persistence
  • 📈 Escalation Support - Seamless handoff to human agents
  • 📊 Chat History - Built-in conversation history with grouping
  • 🎯 Smart Categorization - Ticket categories for better organization
  • ⚡ Lightweight - Optimized bundle size for fast loading
  • 🛡️ Framework Agnostic - Works with React, Vue.js, Angular, and vanilla HTML

📦 Installation

Option 1: CDN (Recommended for quick setup)

<script src="https://unpkg.com/sagegreytechnologies-nkiru-ai-chat-widget-webcomponent@2.6.0/chat-widget.min.js"></script>

Option 2: NPM Install

npm install sagegreytechnologies-nkiru-ai-chat-widget-webcomponent

Option 3: Yarn

yarn add sagegreytechnologies-nkiru-ai-chat-widget-webcomponent

🚀 Quick Start

Vanilla HTML/JavaScript

<!DOCTYPE html>
<html>
<head>
    <title>Your Website</title>
</head>
<body>
    <!-- Your website content -->
    
    <!-- AI Chat Widget -->
    <chat-widget
        api-url="https://your-api.com"          <!-- REQUIRED -->
        tenant-key="pk_your-tenant-key"     <!-- REQUIRED -->
        company-name="Your Company"             <!-- REQUIRED -->
        primary-color="#3b82f6"                 <!-- Optional -->
        title="Chat Support"                    <!-- Optional -->
        subtitle="We're here to help"          <!-- Optional -->
        welcome-message="Hello! How can I help you today?"  <!-- Optional -->
        placeholder="Type your message..."     <!-- Optional -->
    ></chat-widget>

    <!-- Load the Web Component -->
    <script src="https://unpkg.com/sagegreytechnologies-nkiru-ai-chat-widget-webcomponent@2.6.0/chat-widget.min.js"></script>
</body>
</html>

Minimal embed: with tenant-key, the company name, colour, logo, welcome message and privacy policy are loaded from your Nkiru tenant settings, so only api-url and tenant-key are needed. Any attribute you set on the element overrides the tenant setting.

⚠️ Important: The api-url, tenant-key, and company-name attributes are required. If any of these are missing, the widget will display a configuration error instead of the chat interface.

🔧 Framework Integration

React Integration

Method 1: useEffect + DOM Manipulation (Recommended)
import { useEffect, useRef } from 'react';
import 'sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js';

function App() {
  const widgetContainerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (widgetContainerRef.current) {
      // Create the web component element
      const widget = document.createElement('chat-widget');
      
      // Set attributes
      widget.setAttribute('api-url', 'https://your-api.com');
      widget.setAttribute('tenant-key', 'pk_your-tenant-key');
      widget.setAttribute('company-name', 'Your Company');
      widget.setAttribute('primary-color', '#3b82f6');
      widget.setAttribute('position', 'bottom-right');
      widget.setAttribute('title', 'Support Chat');
      widget.setAttribute('subtitle', "We're here to help");
      widget.setAttribute('welcome-message', 'Hello! How can I help you today?');
      widget.setAttribute('placeholder', 'Type your message...');
      
      // Append to container
      widgetContainerRef.current.appendChild(widget);
      
      // Cleanup function
      return () => {
        if (widgetContainerRef.current && widget.parentNode) {
          widgetContainerRef.current.removeChild(widget);
        }
      };
    }
  }, []);

  return (
    <div className="App">
      <h1>My React App</h1>
      {/* Your app content */}
      
      {/* Widget container */}
      <div ref={widgetContainerRef}></div>
    </div>
  );
}

export default App;
Method 2: React.createElement (Alternative)
import React from 'react';
import 'sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js';

function App() {
  return (
    <div className="App">
      <h1>My React App</h1>
      {/* Your app content */}
      
      {/* AI Chat Widget using React.createElement */}
      {React.createElement('chat-widget', {
        'api-url': 'https://your-api.com',
        'tenant-key': 'pk_your-tenant-key',
        'company-name': 'Your Company',
        'primary-color': '#3b82f6',
        'position': 'bottom-right',
        'title': 'Support Chat',
        'subtitle': "We're here to help",
        'welcome-message': 'Hello! How can I help you today?',
        'placeholder': 'Type your message...'
      })}
    </div>
  );
}

export default App;
Method 3: Direct JSX (TypeScript Declaration Required)
// First, add this to your global.d.ts or component file:
declare global {
  namespace JSX {
    interface IntrinsicElements {
      'chat-widget': any;
    }
  }
}

import 'sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js';

function App() {
  return (
    <div className="App">
      <h1>My React App</h1>
      
      <chat-widget
        api-url="https://your-api.com"
        tenant-key="pk_your-tenant-key"
        company-name="Your Company"
        primary-color="#3b82f6"
        position="bottom-right"
        title="Support Chat"
        subtitle="We're here to help"
        welcome-message="Hello! How can I help you today?"
        placeholder="Type your message..."
      />
    </div>
  );
}

export default App;

Vue.js Integration

Vue 3 Composition API
<template>
  <div>
    <h1>My Vue App</h1>
    <!-- Your app content -->
    
    <!-- AI Chat Widget -->
    <chat-widget
      api-url="https://your-api.com"
      tenant-key="pk_your-tenant-key"
      company-name="Your Company"
      primary-color="#3b82f6"
      position="bottom-right"
      title="Support Chat"
      subtitle="We're here to help"
      welcome-message="Hello! How can I help you today?"
      placeholder="Type your message..."
    />
  </div>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(() => {
  // Import the web component
  import('sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js');
});
</script>
Vue 2 Options API
<template>
  <div>
    <h1>My Vue App</h1>
    
    <chat-widget
      api-url="https://your-api.com"
      tenant-key="pk_your-tenant-key"
      company-name="Your Company"
      primary-color="#3b82f6"
      position="bottom-right"
      title="Support Chat"
      subtitle="We're here to help"
      welcome-message="Hello! How can I help you today?"
      placeholder="Type your message..."
    />
  </div>
</template>

<script>
export default {
  name: 'App',
  mounted() {
    // Import the web component
    import('sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js');
  }
}
</script>

Angular Integration

Step 1: Enable Custom Elements
// app.module.ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA] // Add this line
})
export class AppModule { }
Step 2: Import in Component
// app.component.ts
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'my-angular-app';

  ngOnInit() {
    // Import the web component
    import('sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js');
  }
}
Step 3: Use in Template
<!-- app.component.html -->
<h1>My Angular App</h1>
<!-- Your app content -->

<!-- AI Chat Widget -->
<chat-widget
  api-url="https://your-api.com"
  tenant-key="pk_your-tenant-key"
  company-name="Your Company"
  primary-color="#3b82f6"
  position="bottom-right"
  title="Support Chat"
  subtitle="We're here to help"
  welcome-message="Hello! How can I help you today?"
  placeholder="Type your message...">
</chat-widget>

Svelte Integration

<script>
  import { onMount } from 'svelte';
  
  onMount(async () => {
    // Import the web component
    await import('sagegreytechnologies-nkiru-ai-chat-widget-webcomponent/chat-widget.js');
  });
</script>

<h1>My Svelte App</h1>

<chat-widget
  api-url="https://your-api.com"
  tenant-key="pk_your-tenant-key"
  company-name="Your Company"
  primary-color="#3b82f6"
  position="bottom-right"
  title="Support Chat"
  subtitle="We're here to help"
  welcome-message="Hello! How can I help you today?"
  placeholder="Type your message..."
/>

📋 Configuration Attributes

⚠️ Required Attributes

The following attributes are required for the widget to function properly. If any of these are missing, the widget will display a configuration error:

Attribute Type Description
api-url string REQUIRED - Your chat API endpoint
tenant-key string REQUIRED - Public tenant key (pk_...) issued by your Nkiru admin. Safe to include in page HTML
request-timeout number Request timeout in ms (default 30000)
logo-url string Logo shown in the header (https only). Defaults to the tenant's logo
privacy-policy-url string Privacy policy users must accept before chatting. Defaults to the tenant's policy
third-party-api-key string Deprecated - exposes your ticketing key in page HTML. Replace with tenant-key
company-name string REQUIRED - Your company name

🎨 Optional Attributes

These attributes are optional and have default values:

Attribute Type Default Description
primary-color string #3b82f6 Widget color theme
position string bottom-right Widget position (bottom-right, bottom-left, top-right, top-left)
title string Chat Support Widget header title
subtitle string We're here to help Widget header subtitle
welcome-message string Hello! How can I help you today? Initial bot message
placeholder string Type your message... Input field placeholder
user-email string "" Pre-fill user email
user-name string "" Pre-fill user name

🔍 Validation & Error Handling

The widget includes built-in validation that checks for required attributes when the component is initialized:

  • Missing Required Props: If any required attribute is missing, the widget will:
    • Display a configuration error message instead of the chat interface
    • Log detailed error information to the browser console
    • Show which specific attributes are missing

Example Error Display:

Configuration Error
API URL is required
API Key is required

Console Error Example:

ChatWidget: Missing required props: API URL, API Key

✅ Minimum Working Example

<chat-widget
  api-url="https://your-api.com"
  tenant-key="pk_your-tenant-key"
  company-name="Your Company"
></chat-widget>

🎨 CSS Isolation & Shadow DOM

This Web Component uses Shadow DOM to provide complete CSS isolation:

  • ✅ No CSS conflicts: Widget styles won't affect your site
  • ✅ No external interference: Your site styles won't break the widget
  • ✅ Consistent appearance: Widget looks the same across all sites
  • ✅ Framework agnostic: Works with any CSS framework (Bootstrap, Tailwind, etc.)
  • ✅ No CSS imports needed: All styles are encapsulated within the component

Benefits over Traditional Components:

  • 🔒 True Encapsulation: Styles are completely isolated
  • 🚀 No Build Step Required: Works directly in any environment
  • 🎯 Better Performance: Isolated rendering and styling
  • 🛡️ Future Proof: Based on web standards

🔄 Advanced Features

Session Management

  • Automatic Session Restoration - Conversations resume where they left off
  • Local Storage Integration - User preferences and history saved locally
  • Cross-tab Synchronization - Sessions work across multiple browser tabs

Escalation Support

  • Automatic Detection - AI determines when escalation is needed
  • Manual Escalation - Users can request human assistance
  • Agent Handoff - Smooth transition from bot to human agent
  • Status Indicators - Clear visual feedback during escalation

Chat History

  • Grouped by Date - Conversations organized by day
  • Searchable - Easy to find previous conversations
  • Persistent - History maintained across sessions

📱 Browser Support

  • ✅ Chrome 53+ (Full support)
  • ✅ Firefox 63+ (Full support)
  • ✅ Safari 10.1+ (Full support)
  • ✅ Edge 79+ (Full support)
  • ✅ Mobile browsers (iOS Safari, Chrome Mobile)

🐛 Troubleshooting

Widget not appearing

  • Check that the script is loaded correctly
  • Verify API URL and credentials
  • Check browser console for errors
  • Ensure the web component is imported before use

React TypeScript Issues

// Add this to your global.d.ts or component file:
declare global {
  namespace JSX {
    interface IntrinsicElements {
      'chat-widget': any;
    }
  }
}

Vue.js Issues

// In vue.config.js
module.exports = {
  chainWebpack: config => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap(options => {
        options.compilerOptions = {
          ...options.compilerOptions,
          isCustomElement: tag => tag === 'chat-widget'
        }
        return options
      })
  }
}

Angular Issues

Make sure to add CUSTOM_ELEMENTS_SCHEMA to your module:

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})

🔄 Migration from React Widget

If you're upgrading from the React-based widget:

  1. Remove React dependencies: No need for React-specific imports
  2. Update attribute names: camelCase → kebab-case (e.g., primaryColor → primary-color)
  3. Remove CSS imports: Shadow DOM handles all styling
  4. Update integration method: Use one of the framework integration methods above
  5. Enjoy improved CSS isolation: No more style conflicts!

🎯 Best Practices

Performance

  • Lazy Loading: Import the widget only when needed
  • CDN Usage: Use CDN for faster loading
  • Minimal Configuration: Only set attributes you need to customize

Security

  • API Key Protection: The widget only needs the public tenant-key. Your ticketing-system key is stored encrypted on the Nkiru server and never reaches the browser
  • Input Validation: Always validate user inputs on the backend
  • Rate Limiting: Implement rate limiting on your API endpoints

User Experience

  • Clear Messaging: Use descriptive welcome messages
  • Responsive Design: Test on various screen sizes
  • Accessibility: Ensure keyboard navigation works properly

📄 License

MIT License - see LICENSE file for details.

🤝 Support


Made with ❤️ by Sagegrey Technologies

Related Packages

@menni/chatbot

A modern React and Vue chatbot component with customizable UI for integration in...

8,474
@irisidea/kalrav-ai

Kalrav AI chatbot widget for React, Next.js, Vue, Angular, and Vanilla JavaScrip...

3,290
@theonexai/chartsconnect-chat-widget

chartsconnect AI Chat Widget - Universal JavaScript library supporting React, Ne...

5,985
@blockspark/chat-widget

chartsconnect AI Chat Widget - Universal JavaScript library supporting React, Ne...

4,092
@bubblav/ai-chatbot-vue

BubblaV AI chatbot widget for Vue applications

7,715 0

Version History

Version Released License
2.6.0 MIT
2.5.1 MIT
2.5.0 MIT
2.4.0 MIT
2.3.0 MIT