@blumessage/react-chat
v1.5.2
Published
A React TypeScript chat widget component with floating button, theming, and Blumessage API integration
Downloads
110
Maintainers
Readme
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-chatBrowser 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" // → MessageCircleBrowse 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 buildBrowser Versions
Standalone (Includes React)
npm run build:commonjsThis creates dist/index.js which includes React and can be used directly in browsers.
External React (Smaller Bundle)
npm run build:browserThis 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: [email protected]
