@blumessage/react-chat
TypeScript icon, indicating that this package has built-in type declarations

1.5.1 • Public • Published

Blumessage React Chat Component

A React TypeScript chat widget component with floating button, theming, and Blumessage API integration. Features real-time messaging, conversation persistence, error handling, and a modern UI built with Tailwind CSS.

✨ Features

  • 🎈 Floating Chat Widget - Appears as a button, expands to full chat
  • 🎨 Light/Dark Themes - Built-in theme support
  • 💾 Persistent Storage - Save conversations to localStorage or sessionStorage
  • 🔄 Real-time Messaging - Instant API integration with Blumessage
  • 📱 Responsive Design - Works on desktop and mobile
  • 🎯 Flexible Icons - Supports various icon patterns
  • Error Handling - Comprehensive error callbacks
  • 🔧 Highly Customizable - Extensive prop options

Installation

NPM Package (Recommended)

npm i @blumessage/react-chat

Browser Versions

Option 1: Standalone (Includes React)

For the simplest setup with everything included:

<!-- Load the Blumessage Chat component (includes React) -->
<script src="path/to/index.js"></script>

Option 2: External React (Smaller Bundle)

For when you already have React loaded:

<!-- Load React and ReactDOM from CDN -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>

<!-- Load the Blumessage Chat component -->
<script src="path/to/blumessage-chat.browser.js"></script>

See BROWSER_USAGE.md for complete browser usage documentation.

Quick Start

Floating Chat Widget (Default)

import React from 'react';
import { BlumessageChat } from '@blumessage/react-chat';

function App() {
  return (
    <BlumessageChat 
      apiKey="your-blumessage-api-key"
    />
  );
}

Embedded Chat

import React from 'react';
import { BlumessageChat } from '@blumessage/react-chat';

function App() {
  return (
    <BlumessageChat 
      apiKey="your-blumessage-api-key"
      floating={false}
      width="400px"
      height="600px"
    />
  );
}

Complete Props Reference

Prop Type Default Description
Required
apiKey string - Your Blumessage API key
Display & Content
name string "Blumessage AI" Display name for the AI assistant
subtitle string "Online • Instant responses" Subtitle shown under the name
placeholder string "Type your message..." Input placeholder text
theme 'light' | 'dark' 'light' Chat widget theme
primaryColor string "linear-gradient(to right, #3b82f6,rgb(8, 98, 242))" Primary color/gradient
Layout & Sizing
floating boolean true Show as floating widget vs embedded
width string '380px' (medium) Custom width (overrides size)
height string '500px' (medium) Custom height (overrides size)
size 'small' | 'medium' | 'large' 'medium' Predefined size preset
fullScreen boolean false Force full screen mode
Floating Widget Options
buttonText string "Chat with us" Text on floating button
buttonPosition 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' 'bottom-right' Button position
buttonStyle React.CSSProperties - Custom button styles
defaultOpen boolean false Start with chat open
maximizeToggleButton boolean true Show maximize/minimize button
icon string 'message-circle' Icon for button (flexible naming)
Help Bubble Options
showHelpBubble boolean true Show help bubble above floating button
helpBubbleMessage string "👋 If you need help chat with us" Message text in help bubble
helpBubbleIcon string 'hand' Icon for help bubble (supports lucide-react icon names)
helpBubbleShowAfter number 1 Seconds to wait before showing bubble
helpBubbleHideAfter number 5 Seconds to wait before hiding bubble (0 = never hide)
Messages & Data
initialMessages Message[] [] Pre-populate with messages
conversationId string - Continue specific conversation
persistent boolean false Use localStorage vs sessionStorage
showTimestamps boolean false Display timestamps: today="2:00 PM", older="17 July, 1:00 PM"
typingText string "Agent is typing..." Custom text shown while waiting for assistant response
emptyStateText string "Start a conversation!" Text shown when no messages are present
markdown boolean true Enable markdown rendering for messages
disableAutoScroll boolean false Disable automatic scrolling to bottom when new messages arrive
Event Callbacks
onUserMessage (message: Message) => void - Called when user sends message
onAssistantMessage (message: Message) => void - Called when assistant responds
onConversationIdChange (id: string | null) => void - Called when conversation ID changes
onChatWidgetOpen () => void - Called when floating chat opens
onChatWidgetClosed () => void - Called when floating chat closes
onError (error: string, context?: string) => void - Called on any error

Advanced Usage Examples

Dark Theme with Callbacks

<BlumessageChat 
  apiKey="your-api-key"
  theme="dark"
  name="Support Bot"
  onUserMessage={(message) => console.log('User:', message.content)}
  onAssistantMessage={(message) => console.log('Bot:', message.content)}
  onError={(error, context) => console.error(`Error in ${context}:`, error)}
/>

Persistent Storage

<BlumessageChat 
  apiKey="your-api-key"
  persistent={true}  // Saves to localStorage instead of sessionStorage
  onConversationIdChange={(id) => {
    // Optionally save ID to your own storage
    if (id) localStorage.setItem('my-chat-id', id);
  }}
/>

Custom Styling & Size

<BlumessageChat 
  apiKey="your-api-key"
  size="large"
  primaryColor="linear-gradient(45deg, #ff6b6b, #4ecdc4)"
  buttonPosition="bottom-left"
  buttonText="Need Help?"
  icon="headphones"
  maximizeToggleButton={true}
/>

Embedded with Initial Messages

const initialMessages = [
  {
    id: '1',
    role: 'assistant' as const,
    content: 'Hello! How can I help you today?',
    timestamp: Date.now()
  }
];

<BlumessageChat 
  apiKey="your-api-key"
  floating={false}
  width="100%"
  height="500px"
  initialMessages={initialMessages}
  placeholder="Ask me anything..."
/>

Help Bubble Configuration

<BlumessageChat 
  apiKey="your-api-key"
  floating={true}
  showHelpBubble={true}
  helpBubbleMessage="👋 Need assistance? We're here to help!"
  helpBubbleIcon="hand"  // Use hand icon (default)
  helpBubbleShowAfter={3}  // Show after 3 seconds
  helpBubbleHideAfter={10} // Hide after 10 seconds
/>

Custom Help Bubble Icons

<BlumessageChat 
  apiKey="your-api-key"
  floating={true}
  showHelpBubble={true}
  helpBubbleIcon="star"  // Use star icon
  helpBubbleMessage="⭐ Rate our service!"
  helpBubbleShowAfter={2}
  helpBubbleHideAfter={8}
/>

<BlumessageChat 
  apiKey="your-api-key"
  floating={true}
  showHelpBubble={true}
  helpBubbleIcon="lightbulb"  // Use lightbulb icon
  helpBubbleMessage="💡 Got an idea? Let's discuss it!"
  helpBubbleShowAfter={1}
  helpBubbleHideAfter={0}  // Never hide
/>

<BlumessageChat 
  apiKey="your-api-key"
  floating={true}
  showHelpBubble={true}
  helpBubbleIcon="help-circle"  // Use help icon
  helpBubbleMessage="❓ Questions? We're here to help!"
  helpBubbleShowAfter={5}
  helpBubbleHideAfter={15}
/>

### Persistent Help Bubble (Never Hide)

```tsx
<BlumessageChat 
  apiKey="your-api-key"
  floating={true}
  showHelpBubble={true}
  helpBubbleMessage="💬 Questions? Click to chat with us!"
  helpBubbleShowAfter={2}  // Show after 2 seconds
  helpBubbleHideAfter={0}  // Never hide (0 = persistent)
/>

Chat with Timestamps

<BlumessageChat 
  apiKey="your-api-key"
  showTimestamps={true}  // Shows "2:00 PM" or "17 July, 1:00 PM"
  floating={false}
  initialMessages={[
    {
      id: '1',
      role: 'assistant' as const,
      content: 'Message from today',
      timestamp: Date.now() - (60 * 60 * 1000)  // Shows: "2:00 PM" (or "14:00")
    },
    {
      id: '2',
      role: 'user' as const,
      content: 'Message from yesterday',
      timestamp: Date.now() - (24 * 60 * 60 * 1000)  // Shows: "17 July, 1:00 PM"
    }
  ]}
/>

Custom Typing Indicator

<BlumessageChat 
  apiKey="your-api-key"
  typingText="Support agent is typing..."  // Custom loading message
  // Or use different text for different languages:
  // typingText="L'agent écrit..." // French
  // typingText="El agente está escribiendo..." // Spanish
/>

Custom Empty State Text

<BlumessageChat 
  apiKey="your-api-key"
  emptyStateText="Welcome! How can I help you today?"  // Custom empty state message
  // Or use different text for different contexts:
  // emptyStateText="Ask me anything about our products..."
  // emptyStateText="Ready to assist with your questions!"
/>

Disable Auto-Scroll

<BlumessageChat 
  apiKey="your-api-key"
  disableAutoScroll={true}  // Prevents automatic scrolling to bottom
  // Useful when you want users to maintain their scroll position
  // or when implementing custom scroll behavior
/>

Icon Options

The icon prop accepts any lucide-react icon name with flexible naming patterns. The component intelligently matches your input to the appropriate lucide-react icon:

// ✅ Any lucide-react icon works:
icon="message-circle"    // MessageCircle
icon="phone"             // Phone
icon="mail"              // Mail
icon="headphones"        // Headphones
icon="bot"               // Bot
icon="users"             // Users
icon="heart"             // Heart
icon="star"              // Star
icon="zap"               // Zap
icon="settings"          // Settings
icon="help-circle"       // HelpCircle
icon="info"              // Info
icon="alert-triangle"    // AlertTriangle

// ✅ Flexible naming patterns (case-insensitive, ignores hyphens/underscores):
icon="MessageCircle"     // → MessageCircle
icon="message_circle"    // → MessageCircle
icon="message circle"    // → MessageCircle
icon="chat"              // → MessageCircle (smart matching)
icon="messaging"         // → MessageCircle (smart matching)
icon="support"           // → Headphones (smart matching)
icon="email"             // → Mail (smart matching)
icon="call"              // → Phone (smart matching)

// ✅ Default fallback: MessageCircle (if no match found)
icon="unknown-icon"      // → MessageCircle

Browse all available icons at: lucide.dev/icons

Simply use the icon name from lucide-react, and the component will handle the rest!

Error Handling

The onError callback provides detailed error context:

<BlumessageChat 
  apiKey="your-api-key"
  onError={(error, context) => {
    switch(context) {
      case 'missing_api_key':
        // Handle missing API key
        break;
      case 'api_key_validation':
        // Handle invalid API key
        break;
      case 'network_error':
        // Handle network issues
        break;
      case 'conversation_history':
        // Handle history fetch errors
        break;
      case 'message_send':
        // Handle message sending errors
        break;
    }
  }}
/>

External Message Submission

The component supports external message submission through a ref, allowing parent components to programmatically send messages and control the chat widget.

Using the Ref

import React, { useRef } from 'react';
import { BlumessageChat, BlumessageChatRef } from '@blumessage/react-chat';

function App() {
  const chatRef = useRef<BlumessageChatRef>(null);

  const sendExternalMessage = async () => {
    if (chatRef.current) {
      await chatRef.current.sendMessage("Hello from external component!");
    }
  };

  const openChat = () => {
    chatRef.current?.openChat();
  };

  const closeChat = () => {
    chatRef.current?.closeChat();
  };

  const clearChat = () => {
    chatRef.current?.clearConversation();
  };

  const getMessages = () => {
    const messages = chatRef.current?.getMessages();
    console.log('Current messages:', messages);
  };

  const getToken = () => {
    const token = chatRef.current?.getToken();
    console.log('Current conversation token:', token);
  };

  return (
    <div>
      <button onClick={sendExternalMessage}>Send External Message</button>
      <button onClick={openChat}>Open Chat</button>
      <button onClick={closeChat}>Close Chat</button>
      <button onClick={clearChat}>Clear Chat</button>
      <button onClick={getMessages}>Get Messages</button>
      <button onClick={getToken}>Get Token</button>
      
      <BlumessageChat
        ref={chatRef}
        apiKey="your-api-key"
        floating={true}
      />
    </div>
  );
}

Available Ref Methods

Method Type Description
sendMessage(message: string) Promise<void> Send a message programmatically
openChat() void Open the floating chat widget
closeChat() void Close the floating chat widget
clearConversation() void Clear all messages and reset conversation
getMessages() Message[] Get current messages array
getToken() string | null Get current conversation token

Complete Example with External Controls

import React, { useRef, useState } from 'react';
import { BlumessageChat, BlumessageChatRef } from '@blumessage/react-chat';

function App() {
  const [externalMessage, setExternalMessage] = useState('');
  const chatRef = useRef<BlumessageChatRef>(null);

  const handleSendExternalMessage = async () => {
    if (!externalMessage.trim() || !chatRef.current) return;
    
    try {
      await chatRef.current.sendMessage(externalMessage);
      setExternalMessage('');
      console.log('External message sent successfully');
    } catch (error) {
      console.error('Failed to send external message:', error);
    }
  };

  return (
    <div>
      <div style={{ marginBottom: '20px' }}>
        <input
          type="text"
          value={externalMessage}
          onChange={(e) => setExternalMessage(e.target.value)}
          placeholder="Type a message to send externally..."
          onKeyPress={(e) => e.key === 'Enter' && handleSendExternalMessage()}
        />
        <button onClick={handleSendExternalMessage}>Send</button>
        <button onClick={() => chatRef.current?.openChat()}>Open Chat</button>
        <button onClick={() => chatRef.current?.closeChat()}>Close Chat</button>
        <button onClick={() => chatRef.current?.clearConversation()}>Clear Chat</button>
      </div>
      
      <BlumessageChat
        ref={chatRef}
        apiKey="your-api-key"
        floating={true}
        onUserMessage={(message) => console.log('User message:', message)}
        onAssistantMessage={(message) => console.log('Assistant message:', message)}
      />
    </div>
  );
}

TypeScript Support

Full TypeScript definitions included:

import { BlumessageChat, Message, BlumessageChatProps, BlumessageChatRef } from '@blumessage/react-chat';

interface Message {
  id: string;
  role: 'user' | 'assistant';
  content: string;
  timestamp: number;
}

interface BlumessageChatRef {
  sendMessage: (message: string) => Promise<void>;
  openChat: () => void;
  closeChat: () => void;
  clearConversation: () => void;
  getMessages: () => Message[];
  getToken: () => string | null;
}

Storage Behavior

  • SessionStorage (default): Conversations persist until browser tab closes
  • LocalStorage (persistent=true): Conversations persist across browser sessions
  • Automatic cleanup: Invalid conversation IDs are automatically cleared
  • History restoration: Previous conversations load automatically on component mount

Browser Support

  • Modern browsers with ES2017+ support
  • React 18+
  • TypeScript 4.5+

Building

Standard Build (ES Modules)

npm run build

Browser Versions

Standalone (Includes React)

npm run build:commonjs

This creates dist/index.js which includes React and can be used directly in browsers.

External React (Smaller Bundle)

npm run build:browser

This creates dist/blumessage-chat.browser.js which requires React to be loaded separately.

License

UNLICENSED - For use only by customers with an active Blumessage subscription.

Support

For feature requests, technical support and assistance, please contact us at: contact@blumessage.com

Package Sidebar

Install

npm i @blumessage/react-chat

Weekly Downloads

195

Version

1.5.1

License

UNLICENSED

Unpacked Size

1.76 MB

Total Files

13

Last publish

Collaborators

  • mihaizhao