
Research
/Security News
Critical Vulnerability in NestJS Devtools: Localhost RCE via Sandbox Escape
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
@blumessage/react-chat
Advanced tools
A React TypeScript chat widget component with floating button, theming, and Blumessage API integration
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.
npm i @blumessage/react-chat
import React from 'react';
import { BlumessageChat } from '@blumessage/react-chat';
function App() {
return (
<BlumessageChat
apiKey="your-blumessage-api-key"
/>
);
}
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"
/>
);
}
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) |
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 |
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 |
<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)}
/>
<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);
}}
/>
<BlumessageChat
apiKey="your-api-key"
size="large"
primaryColor="linear-gradient(45deg, #ff6b6b, #4ecdc4)"
buttonPosition="bottom-left"
buttonText="Need Help?"
icon="headphones"
maximizeToggleButton={true}
/>
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..."
/>
<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"
}
]}
/>
<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
/>
<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!"
/>
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!
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;
}
}}
/>
The component supports external message submission through a ref, allowing parent components to programmatically send messages and control the chat widget.
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>
);
}
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 |
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>
);
}
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;
}
UNLICENSED - For use only by customers with an active Blumessage subscription.
For feature requests, technical support and assistance, please contact us at: contact@blumessage.com
FAQs
A React TypeScript chat widget component with floating button, theming, and Blumessage API integration
The npm package @blumessage/react-chat receives a total of 9 weekly downloads. As such, @blumessage/react-chat popularity was classified as not popular.
We found that @blumessage/react-chat demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Β It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
/Security News
A flawed sandbox in @nestjs/devtools-integration lets attackers run code on your machine via CSRF, leading to full Remote Code Execution (RCE).
Product
Customize license detection with Socketβs new license overlays: gain control, reduce noise, and handle edge cases with precision.
Product
Socket now supports Rust and Cargo, offering package search for all users and experimental SBOM generation for enterprise projects.