Introducing Rich Components: Beyond Text in Conversations
Conversations aren't just text. Today we're launching Rich Components—interactive elements that let you embed calendars, forms, payments, and custom React components directly in conversations.
Why Rich Components?
Traditional chatbots are limited to text and simple buttons. But real conversations need more:
Customer: "I'd like to book a table"
Bot (old way): "What date? (type in format MM/DD/YYYY)"
Customer: "08/30/2024"
Bot: "What time? (type in format HH:MM)"
Customer: "7pm"
Bot: "Sorry, 7pm isn't available. Try 6:30pm or 7:30pm"
Frustrating. Now watch this:
Customer: "I'd like to book a table"
Bot (new way): [Shows calendar picker with available dates highlighted]
Customer: [Selects August 30]
Bot: [Shows time slots: 6:30pm, 7:30pm, 8:30pm as clickable buttons]
Customer: [Taps 7:30pm]
Bot: "Perfect! Table for how many?" [Shows number picker: 2, 4, 6, 8]
Much better.
Available Components
1. Calendar Picker
Use cases:
- Booking appointments
- Scheduling demos
- Selecting delivery dates
- Choosing event dates
Example:
javascript
{
type: 'calendar',
availableDates: ['2024-08-30', '2024-08-31', '2024-09-01'],
minDate: '2024-08-29',
maxDate: '2024-12-31',
onSelect: (date) => handleDateSelection(date)
}
Features:
2. Form Components
Use cases:
Example:
javascript
{
type: 'form',
fields: [
{ name: 'email', label: 'Email', type: 'email', required: true },
{ name: 'company', label: 'Company', type: 'text' },
{ name: 'size', label: 'Company Size', type: 'select', options: ['1-10', '11-50', '51-200', '200+'] }
],
submitLabel: 'Get Demo',
onSubmit: (data) => handleFormSubmit(data)
}
Features:
3. Payment Components
Use cases:
Example:
javascript
{
type: 'payment',
amount: 99.00,
currency: 'USD',
description: 'Pro Plan - Monthly',
provider: 'stripe', // or 'paypal'
onSuccess: (paymentId) => handlePayment(paymentId)
}
Features:
4. Product Cards
Use cases:
Example:
javascript
{
type: 'product_card',
products: [
{
id: 'prod_123',
name: 'Starter Plan',
image: 'https://...',
price: '$29/mo',
features: ['1,000 conversations', 'Email support', 'Basic analytics'],
primaryAction: { label: 'Choose Plan', action: 'select_starter' }
}
]
}
Features:
5. Custom React Components
Use cases:
Example:
javascript
{
type: 'custom',
component: 'MyCustomBookingFlow',
props: {
availableTimes: [...],
userId: '123',
onComplete: (booking) => handleBooking(booking)
}
}
Your custom component:
javascript
export function MyCustomBookingFlow({ availableTimes, userId, onComplete }) {
// Build whatever you want with React
return (
{/* Your custom UI here */}
);
}
How It Works
1. Bot Sends Component
javascript
async function handleMessage(message) {
if (message.includes('book a table')) {
return {
type: 'message',
content: "I'd love to help you book a table. What date works for you?",
components: [
{
type: 'calendar',
availableDates: await getAvailableDates(),
onSelect: (date) => ({ action: 'date_selected', date })
}
]
};
}
}
2. User Interacts
The component renders in the conversation:
3. Bot Responds
``javascript
if (action === 'date_selected') {
return {
type: 'message',
content: Great! What time on ${formatDate(date)}?,
components: [
{
type: 'button_group',
buttons: await getAvailableTimes(date)
}
]
};
}
Real-World Examples
Example 1: Restaurant Booking
javascript
// Step 1: Date selection
bot.send({
content: "When would you like to dine with us?",
components: [{
type: 'calendar',
availableDates: getNextMonth(),
onSelect: (date) => ({ action: 'select_time', date })
}]
});
// Step 2: Time selection
bot.send({
content: "Available times on Aug 30:",
components: [{
type: 'button_group',
buttons: ['6:30 PM', '7:30 PM', '8:30 PM'],
onSelect: (time) => ({ action: 'select_party_size', time })
}]
});
// Step 3: Party size
bot.send({
content: "Table for how many?",
components: [{
type: 'button_group',
buttons: ['2', '4', '6', '8+'],
onSelect: (size) => ({ action: 'confirm_booking', size })
}]
});
// Step 4: Confirmation
bot.send({
content: "Perfect! Confirming your reservation...",
components: [{
type: 'booking_summary',
date: 'Aug 30',
time: '7:30 PM',
party: 4,
actions: [
{ label: 'Confirm', action: 'book' },
{ label: 'Change', action: 'restart' }
]
}]
});
Example 2: E-commerce Shopping
javascript
// Browse products
bot.send({
content: "Here are our best sellers:",
components: [{
type: 'product_carousel',
products: [
{
name: 'Widget Pro',
image: '...',
price: '$99',
rating: 4.5,
action: 'view_product_123'
},
// More products...
]
}]
});
// Product details
bot.send({
content: "Widget Pro",
components: [{
type: 'product_detail',
images: ['img1.jpg', 'img2.jpg'],
price: '$99',
description: '...',
variants: [
{ name: 'Color', options: ['Black', 'White', 'Blue'] },
{ name: 'Size', options: ['S', 'M', 'L', 'XL'] }
],
primaryAction: { label: 'Add to Cart', action: 'add_to_cart' }
}]
});
// Checkout
bot.send({
content: "Ready to checkout?",
components: [{
type: 'cart_summary',
items: [...],
total: '$99',
actions: [
{ label: 'Checkout', action: 'checkout' },
{ label: 'Continue Shopping', action: 'browse' }
]
}]
});
// Payment
bot.send({
content: "Complete your purchase:",
components: [{
type: 'payment',
amount: 99.00,
currency: 'USD',
provider: 'stripe'
}]
});
Example 3: Lead Qualification
javascript
// Collect info with form
bot.send({
content: "Let's get started. Tell us a bit about your needs:",
components: [{
type: 'form',
fields: [
{ name: 'name', label: 'Name', required: true },
{ name: 'email', label: 'Email', type: 'email', required: true },
{ name: 'company', label: 'Company' },
{ name: 'employees', label: 'Company Size', type: 'select', options: ['1-10', '11-50', '51-200', '200+'] },
{ name: 'use_case', label: 'Primary Use Case', type: 'textarea' }
],
submitLabel: 'Continue'
}]
});
// Follow-up based on responses
if (data.employees === '200+') {
bot.send({
content: "Great! Let's schedule a call with our enterprise team.",
components: [{
type: 'calendar',
integration: 'calendly',
url: 'https://calendly.com/enterprise-demo'
}]
});
} else {
bot.send({
content: "Perfect! Here's a quick demo video:",
components: [{
type: 'video',
url: 'https://youtube.com/demo',
actions: [
{ label: 'Start Free Trial', action: 'sign_up' },
{ label: 'Schedule Demo', action: 'book_demo' }
]
}]
});
}
Technical Details
Component Rendering
Rich Components use React for rendering:
javascript
// Bot returns component spec
{
type: 'calendar',
availableDates: ['2024-08-30'],
// ...
}
// Widget converts to React component
availableDates={['2024-08-30']} onSelect={handleSelect} /> function CalendarComponent({ availableDates, onSelect }) { const [selectedDate, setSelectedDate] = useState(null); const handleDateClick = (date) => { setSelectedDate(date); onSelect(date); // Notify bot }; return } { type: 'calendar', theme: { primaryColor: '#0066cc', borderRadius: '8px', fontFamily: 'Inter, sans-serif' } } { type: 'custom', component: 'MyComponent', styles: .my-component { background: linear-gradient(to right, #667eea, #764ba2); } } npm install @ilq/sdk@latest bot.onMessage(async (message) => { return { content: "Choose a date:", components: [{ type: 'calendar', onSelect: (date) => ({ action: 'date_selected', date }) }] }; }); bot.onAction('date_selected', async ({ date }) => { return { content: You selected ${date} // Next component or final response }; }); `` Coming soon: Questions? Email us at hello@ilq.ai --- *Rich Components are available now for all ilq.ai customers. Try them today →*
javascript
State Management
Components maintain their own state:
javascript
Custom Styling
Match your brand:
javascript
Or inject custom CSS:
bash
Performance
Fast: Components are lazy-loaded
Small: Only load what you use
Cached: Shared components cached across conversations
Size:
Pricing
Rich Components are included in all plans:
Get Started
1. Update your SDK:
javascript
2. Return component in your handler:
javascript
3. Handle component actions:
,
What's Next
