JavaScript
Stripe Elements-style API for programmatic control of the feedback widget
The JavaScript API provides a Stripe Elements-style interface for full programmatic control. Perfect for SPAs, JavaScript apps, or any framework.
Installation
npm install @cobbl-ai/feedback-widgetBasic Usage
import { cobblWidget } from '@cobbl-ai/feedback-widget'
// Create a widget instance
const widget = cobblWidget.create({
runId: 'prompt-run-id',
})
// Mount to a container
widget.mount('#feedback-container')API Reference
cobblWidget.create()
Create a new widget instance with configuration:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
variant: 'trigger',
position: 'bottom-right',
triggerButtonText: 'Rate this response',
onSuccess: (feedbackId) => {
console.log('Feedback submitted:', feedbackId)
},
onError: (error) => {
console.error('Feedback failed:', error)
},
})You can also create a widget from an element with data attributes:
const element = document.getElementById('my-widget')
const widget = cobblWidget.create(element)Configuration Options
All available options for cobblWidget.create():
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
runId | string | Yes | — | Run ID from prompt execution |
variant | 'trigger' | 'thumbs' | 'inline' | No | 'trigger' | Display variant |
position | WidgetPosition | No | 'bottom-right' | Flyout position |
triggerButtonText | string | No | 'Give Feedback' | Trigger button text |
colorScheme | 'auto' | 'light' | 'dark' | No | 'auto' | Color scheme mode |
onSuccess | (feedbackId: string) => void | No | — | Success callback |
onError | (error: Error) => void | No | — | Error callback |
widget.mount()
Mount the widget to a DOM element:
// Mount using a CSS selector
widget.mount('#feedback-container')
// Mount using a DOM element
const container = document.getElementById('feedback-container')
widget.mount(container)The container element must exist in the DOM before calling mount.
widget.update()
Update the widget configuration dynamically:
// Update a single property
widget.update({ runId: 'new-run-id' })
// Update multiple properties
widget.update({
runId: 'new-run-id',
variant: 'thumbs',
position: 'top',
})widget.getConfig()
Get the current widget configuration:
const config = widget.getConfig()
console.log(config.runId)
console.log(config.variant)widget.destroy()
Unmount and clean up the widget:
widget.destroy()Always call destroy when removing the widget to properly clean up event listeners and DOM elements.
WidgetInstance Interface
interface WidgetInstance {
mount(container: string | HTMLElement): void
update(config: Partial<FeedbackWidgetConfig>): void
destroy(): void
getConfig(): FeedbackWidgetConfig
}Display Variants
Trigger Variant (Default)
A text button that opens the feedback flyout:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
variant: 'trigger',
triggerButtonText: 'Give Feedback',
})
widget.mount('#container')Thumbs Variant
Thumbs up/down buttons that immediately register feedback:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
variant: 'thumbs',
})
widget.mount('#container')Inline Variant
Full feedback form rendered directly:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
variant: 'inline',
})
widget.mount('#container')Flyout Positioning
Control where the flyout appears relative to the trigger:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
variant: 'trigger',
position: 'top-right',
})
widget.mount('#container')Available positions:
top-left,top,top-rightleft,rightbottom-left,bottom,bottom-right(default)
The flyout automatically adjusts if it would overflow the viewport.
Color Scheme
Control the widget's color scheme:
// Auto (default) - follows system preference
const widget = cobblWidget.create({
runId: 'prompt-run-id',
colorScheme: 'auto',
})
// Force light theme
const lightWidget = cobblWidget.create({
runId: 'prompt-run-id',
colorScheme: 'light',
})
// Force dark theme
const darkWidget = cobblWidget.create({
runId: 'prompt-run-id',
colorScheme: 'dark',
})Dynamic Color Scheme Updates
Update the color scheme at runtime:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
colorScheme: 'auto',
})
widget.mount('#container')
// Later, switch to dark mode
widget.update({ colorScheme: 'dark' })With auto mode, the widget automatically updates when the user changes their
system color scheme preference.
See Styling for customizing colors per scheme.
Complete Example
import { cobblWidget } from '@cobbl-ai/feedback-widget'
import { CobblAdminClient } from '@cobbl-ai/sdk'
const client = new CobblAdminClient({ apiKey: 'your-api-key' })
// Store widget reference for cleanup
let feedbackWidget: ReturnType<typeof cobblWidget.create> | null = null
const runPromptAndShowWidget = async () => {
// Run the prompt
const result = await client.runPrompt('my-prompt', {
topic: 'AI Safety',
})
// Display the response
document.getElementById('response')!.textContent = result.output
// Clean up existing widget if any
if (feedbackWidget) {
feedbackWidget.destroy()
}
// Create and mount feedback widget
feedbackWidget = cobblWidget.create({
runId: result.runId,
position: 'bottom-right',
triggerButtonText: 'Rate this response',
onSuccess: (feedbackId) => {
console.log('Feedback submitted:', feedbackId)
},
})
feedbackWidget.mount('#feedback-container')
}
// Clean up when navigating away
window.addEventListener('beforeunload', () => {
feedbackWidget?.destroy()
})Multiple Widgets
You can have multiple widget instances on the same page:
import { cobblWidget } from '@cobbl-ai/feedback-widget'
// Create widgets for different responses
const widget1 = cobblWidget.create({ runId: 'run-1', variant: 'thumbs' })
const widget2 = cobblWidget.create({ runId: 'run-2', variant: 'thumbs' })
const widget3 = cobblWidget.create({ runId: 'run-3', variant: 'inline' })
// Mount to different containers
widget1.mount('#response-1-feedback')
widget2.mount('#response-2-feedback')
widget3.mount('#response-3-feedback')Dynamic Updates
Update the widget when the run changes:
const widget = cobblWidget.create({
runId: 'initial-run-id',
})
widget.mount('#container')
// Later, update the run ID
const newResult = await client.runPrompt('my-prompt', { topic: 'New Topic' })
widget.update({ runId: newResult.runId })Event Callbacks
Handle success and error events:
const widget = cobblWidget.create({
runId: 'prompt-run-id',
onSuccess: (feedbackId) => {
// Called when feedback is successfully submitted
console.log('Feedback ID:', feedbackId)
// Show a toast notification
showToast('Thanks for your feedback!')
// Track analytics
analytics.track('feedback_submitted', { feedbackId })
},
onError: (error) => {
// Called when feedback submission fails
console.error('Feedback error:', error.message)
// Show error to user
showToast('Failed to submit feedback. Please try again.')
},
})Styling
Apply custom styles using CSS variables:
#feedback-container {
--cobbl-primary: #6366f1;
--cobbl-primary-hover: #4f46e5;
--cobbl-flyout-width: 350px;
}See Styling for the complete list of CSS variables.
TypeScript Support
Full TypeScript support is included:
import { cobblWidget } from '@cobbl-ai/feedback-widget'
import type {
FeedbackWidgetConfig,
WidgetInstance,
ColorScheme,
} from '@cobbl-ai/feedback-widget'
const config: FeedbackWidgetConfig = {
runId: 'prompt-run-id',
variant: 'trigger',
colorScheme: 'auto',
}
const widget: WidgetInstance = cobblWidget.create(config)See TypeScript for type definitions.