@biudon-dev/barca-chat-widget
v1.0.13
Published
Voice chat widget for BarcaMobile with ElevenLabs integration
Readme
@biudon-dev/barca-chat-widget
A voice chat widget for BarcaMobile with ElevenLabs integration, featuring Barcelona FC-themed UI.
Installation
npm install @biudon-dev/barca-chat-widgetExamples
Check out the examples folder in the NPM package for complete integration examples:
examples/nextjs-integration- Full Next.js integration with widget coordination
You can also view the examples on GitHub:
npx degit biudon-dev/barca-chat-widget/examples/nextjs-integration my-widget-test
cd my-widget-test
npm install
npm run devQuick Start
import { BarcaChatProvider, BarcaChatWidget } from '@biudon-dev/barca-chat-widget';
import '@biudon-dev/barca-chat-widget/dist/barca-chat.css';
function App() {
return (
<BarcaChatProvider config={{
agentId: process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID,
onTextChatSelected: () => {
// Show your existing text chat system
console.log('User selected text chat');
}
}}>
<div>
{/* Your app content */}
<h1>Welcome to BarcaMobile</h1>
{/* The chat widget will appear as a floating button */}
<BarcaChatWidget />
</div>
</BarcaChatProvider>
);
}
export default App;Next.js Integration
1. Install the package
npm install @biudon-dev/barca-chat-widget2. Create a client component wrapper
Create components/ChatWidget.tsx:
'use client';
import { BarcaChatProvider, BarcaChatWidget } from '@biudon-dev/barca-chat-widget';
import '@biudon-dev/barca-chat-widget/dist/barca-chat.css';
interface ChatWidgetProps {
agentId: string;
onTextChatSelected?: () => void;
}
export default function ChatWidget({ agentId, onTextChatSelected }: ChatWidgetProps) {
return (
<BarcaChatProvider config={{
agentId,
onTextChatSelected,
onError: (error) => {
console.error('Chat widget error:', error);
}
}}>
<BarcaChatWidget />
</BarcaChatProvider>
);
}3. Use in your app
// app/page.tsx or pages/index.tsx
import ChatWidget from '@/components/ChatWidget';
export default function Home() {
const handleTextChatSelected = () => {
// Integrate with your existing text chat system
// For example: open a modal, redirect to chat page, etc.
window.open('/text-chat', '_blank');
};
return (
<main>
<h1>Welcome to BarcaMobile</h1>
<ChatWidget
agentId={process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID!}
onTextChatSelected={handleTextChatSelected}
/>
</main>
);
}4. Environment Variables
Add to your .env.local:
NEXT_PUBLIC_ELEVENLABS_AGENT_ID=your_agent_id_hereEnvironment Variable Validation Example
For production apps, validate that required environment variables are set:
// utils/validateEnv.ts
export const validateEnvironment = () => {
const requiredVars = {
NEXT_PUBLIC_ELEVENLABS_AGENT_ID: process.env.NEXT_PUBLIC_ELEVENLABS_AGENT_ID
};
const missingVars = Object.entries(requiredVars)
.filter(([_, value]) => !value)
.map(([key]) => key);
if (missingVars.length > 0) {
throw new Error(
`Missing required environment variables: ${missingVars.join(', ')}\n` +
'Please check your .env.local file'
);
}
return requiredVars;
};
// app/layout.tsx or pages/_app.tsx
import { validateEnvironment } from '@/utils/validateEnv';
// Validate on app initialization
if (process.env.NODE_ENV === 'production') {
validateEnvironment();
}Configuration Options
interface BarcaChatConfig {
// Required
agentId: string; // ElevenLabs agent ID
// Optional
apiKey?: string; // Basic auth token
onTextChatSelected?: () => void; // Callback when text chat is selected
hideOnTextSelection?: boolean; // Auto-hide widget on text selection (default: true)
// Lifecycle hooks
onWidgetOpen?: () => void;
onWidgetClose?: () => void;
onConversationStart?: () => void;
onConversationEnd?: () => void;
onError?: (error: Error) => void;
// Customization
position?: 'bottom-right' | 'bottom-left'; // Widget position (default: 'bottom-right')
theme?: {
primaryColor?: string; // Barcelona blue
secondaryColor?: string; // Barcelona red
accentColor?: string; // Barcelona gold
};
// Text chat option customization
textChatLabel?: string; // Default: "Text Chat"
textChatDescription?: string; // Default: "Type your messages"
}Widget Coordination (Multiple Widgets)
If you need to coordinate between the voice widget and your existing text chat to prevent overlaps, use the built-in Widget Manager:
import { BarcaChatProvider, BarcaChatWidget, widgetManager } from '@biudon-dev/barca-chat-widget';
// Enable widget manager in your config
<BarcaChatProvider config={{
agentId: 'your-agent-id',
useWidgetManager: true, // ← Enable coordination
onTextChatSelected: () => {
// Widget manager handles the transition automatically
}
}}>
<BarcaChatWidget />
</BarcaChatProvider>
// In your text chat component
import { widgetManager } from '@biudon-dev/barca-chat-widget';
// Open text chat
widgetManager.requestOpen('text');
// Close text chat
widgetManager.requestClose('text');
// Subscribe to state changes
widgetManager.subscribe((state) => {
if (state.activeWidget === 'text') {
// Show your text chat
} else {
// Hide your text chat
}
});See the examples/nextjs-integration folder for a complete working example.
Handling Text Chat Selection
When users select "Text Chat" from the widget, the onTextChatSelected callback is triggered. Use this to integrate with your existing text chat system:
const config = {
agentId: 'your-agent-id',
onTextChatSelected: () => {
// Option 1: Open existing chat in new window
window.open('/chat', '_blank');
// Option 2: Show a modal
setShowChatModal(true);
// Option 3: Navigate to chat page
router.push('/chat');
// Option 4: Show inline chat component
setChatMode('text');
},
hideOnTextSelection: true, // Widget will hide automatically
};Programmatic Control
Use the useBarcaChat hook for programmatic control:
import { useBarcaChat } from '@biudon-dev/barca-chat-widget';
function MyComponent() {
const chat = useBarcaChat();
return (
<div>
<button onClick={chat.openWidget}>Open Chat</button>
<button onClick={chat.closeWidget}>Close Chat</button>
<button onClick={chat.startVoiceChat}>Start Voice Chat</button>
<button onClick={chat.endVoiceChat}>End Voice Chat</button>
<p>Status: {chat.conversationStatus}</p>
<p>Open: {chat.isOpen ? 'Yes' : 'No'}</p>
</div>
);
}Styling
The widget includes scoped CSS to prevent conflicts. All classes are prefixed with .barca-chat-.
Custom Styling
You can override styles by targeting the scoped classes:
/* Custom button color */
.barca-chat-toggle {
background: linear-gradient(135deg, #your-color-1, #your-color-2) !important;
}
/* Custom widget size */
.barca-chat-conversation {
width: 32rem !important;
height: 85vh !important;
}TypeScript Support
The package includes full TypeScript definitions:
import type { BarcaChatConfig, BarcaChatAPI } from '@biudon-dev/barca-chat-widget';
const config: BarcaChatConfig = {
agentId: 'your-agent-id',
position: 'bottom-left',
onError: (error: Error) => {
console.error(error.message);
}
};Error Handling
const config = {
agentId: 'your-agent-id',
onError: (error: Error) => {
// Log to your error tracking service
console.error('Chat widget error:', error);
// Show user-friendly message
toast.error('Voice chat temporarily unavailable');
}
};Bundle Size
- Total: ~30KB gzipped
- CSS: ~5KB gzipped
- JS: ~25KB gzipped
Browser Support
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
Requirements
- React 17+
- Microphone access for voice chat
- ElevenLabs agent ID
Troubleshooting
Widget not appearing
- Ensure you've imported the CSS file
- Check that the
BarcaChatProviderwraps your component - Verify the
agentIdis provided
Voice chat not working
- Check microphone permissions in browser
- Verify the ElevenLabs agent ID is correct
- Check browser console for errors
Styling conflicts
- All widget styles are scoped with
.barca-chat-prefix - Use
!importantif you need to override widget styles
TypeScript errors
- Ensure you have
@types/reactand@types/react-dominstalled - The package includes its own type definitions
Support
For issues and questions:
- Check the troubleshooting section above
- Review the configuration options
- Ensure all requirements are met
License
MIT
