Embed Widget
Add an AI chat widget to any website with a single script tag. Works like Intercom, powered by your ASH agents.
One Script
Just paste a script tag. No React, no build tools required on the host site.
Floating or Embedded
Show as a floating chat bubble or embed directly into any container element.
Fully Customizable
Match your brand with custom colors, sizes, position, and greeting messages.
Quick Start
Add this snippet before </body> on any page:
<!-- ASH Widget -->
<script>
window.AshSettings = {
apiBasePath: 'https://your-api.com/api',
agent: 'your-agent-slug'
};
(function(){var w=window;var a=w.Ash;if(typeof a==="function"){a('boot',w.AshSettings);}else{var d=document;var i=function(){i.c(arguments);};i.q=[];i.c=function(args){i.q.push(args);};w.Ash=i;var l=function(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://cdn.your-domain.com/ash-widget.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);};if(document.readyState==='complete'){l();}else if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})();
</script>Configuration Options
Customize the widget to match your needs:
window.AshSettings = {
// Required
apiBasePath: 'https://your-api.com/api',
// Optional: Agent slug (auto-selects first agent if not specified)
agent: 'your-agent-slug',
// Position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' | 'embedded'
position: 'bottom-right',
// For embedded mode, specify the container element ID
containerId: 'my-widget-container',
// Resume an existing session
sessionId: 'session_abc123',
// Start with widget open
open: false,
// Custom launcher button text
launcherText: 'Chat with us',
// Hide the default launcher (for custom triggers)
hideLauncher: false,
// Theme customization
theme: {
accentColor: '#ccff00', // Primary color
backgroundColor: '#0a0a0a', // Widget background
textColor: '#f3f4f6', // Text color
borderRadius: '16px' // Border radius
},
// Widget dimensions (floating mode only)
size: {
width: '400px',
height: '600px',
maxHeight: '80vh'
},
// Z-index (default: max z-index)
zIndex: 2147483647,
// Greeting message shown before first interaction
greeting: 'Hi! How can I help you today?',
// Input placeholder
placeholder: 'Type a message...',
// Initial context data (passed with every message)
context: {
userId: 'user_123',
page: 'pricing',
customData: { plan: 'pro' }
}
};JavaScript API
Control the widget programmatically from your JavaScript code:
// Open/close the widget
Ash('open');
Ash('close');
Ash('toggle');
// Show/hide the entire widget
Ash('show');
Ash('hide');
// Show/hide just the launcher button
Ash('showLauncher');
Ash('hideLauncher');
// Update settings dynamically
Ash('update', {
greeting: 'New greeting!',
theme: { accentColor: '#ff6b6b' }
});
// Shutdown and remove the widget
Ash('shutdown');
// Re-initialize with new settings
Ash('boot', {
apiBasePath: 'https://new-api.com',
agent: 'different-agent'
});Context & Data API
Push data to the widget and send messages programmatically. This enables your app to share context with the AI agent.
// Set context data (replaces existing context)
Ash('setContext', {
userId: 'user_123',
currentPage: 'checkout',
cartItems: ['item_1', 'item_2']
});
// Update context (merges with existing)
Ash('updateContext', { cartTotal: 99.99 });
// Clear all context
Ash('clearContext');
// Send a message programmatically
Ash('sendMessage', 'What products do you recommend?');
// Send a message with additional one-time context
Ash('sendMessageWithContext', 'Help me with this', {
selectedProduct: 'SKU-12345',
error: 'Payment failed'
});
// Query current state
Ash('getSessionId', (sessionId) => {
console.log('Current session:', sessionId);
});
Ash('getContext', (context) => {
console.log('Current context:', context);
});
Ash('getMessages', (messages) => {
console.log('Conversation history:', messages);
});Event Hooks
Listen to widget events to integrate with your application. Perfect for analytics, UI updates, or custom tool handling.
window.AshSettings = {
apiBasePath: 'https://your-api.com/api',
// Basic lifecycle events
onOpen: () => console.log('Widget opened'),
onClose: () => console.log('Widget closed'),
onSessionStart: (sessionId) => console.log('Session:', sessionId),
// Message events
onMessageSent: (message) => {
analytics.track('chat_message_sent', { message });
},
onMessageReceived: (message) => {
analytics.track('chat_message_received');
},
// Streaming events
onStreamStart: () => {
showTypingIndicator();
},
onStreamDelta: (delta, fullContent) => {
// Called for each chunk of streaming content
updateLivePreview(fullContent);
},
onStreamEnd: (fullContent) => {
hideTypingIndicator();
},
// Tool events - react to agent actions!
onToolUse: (event) => {
console.log('Agent using tool:', event.toolName, event.input);
if (event.toolName === 'create_order') {
showOrderPending(event.input);
}
},
onToolResult: (event) => {
console.log('Tool result:', event.result);
if (!event.isError) {
refreshOrderStatus();
}
},
// Error handling
onError: (error, code) => {
console.error('Widget error:', error, code);
showErrorToast(error);
},
// Catch-all event handler
onEvent: (event) => {
// All events come through here
analytics.track('ash_event', { type: event.type, ...event });
}
};Embedded Mode
Instead of a floating widget, embed the chat directly into your page layout. The widget will fill its container 100%.
<!-- Container with fixed height -->
<div id="chat-container" style="height: 600px;"></div>
<script>
window.AshSettings = {
apiBasePath: 'https://your-api.com/api',
agent: 'support-agent',
position: 'embedded', // Fills container 100%
containerId: 'chat-container',
theme: { borderRadius: '12px' }
};
// ... loader script
</script>Note: In embedded mode, make sure to set a height on the container element. No floating launcher button is shown — the widget is always visible.
Self-Hosting the Widget
Build and host the widget bundle on your own infrastructure:
# Build the embed bundle
cd harness/packages/ash-ai
pnpm build:embed
# Output: dist/ash-widget.js (~50KB gzipped)Serve dist/ash-widget.js from your CDN and update the src in the loader script.
Generating Embed Code
Use the helper functions to generate embed snippets programmatically:
import { generateEmbedSnippet } from '@conviction-labs/ash-ai/embed';
const snippet = generateEmbedSnippet('https://cdn.example.com/ash-widget.js', {
apiBasePath: 'https://api.example.com',
agent: 'support-agent',
greeting: 'Hello! How can I help?',
theme: { accentColor: '#0066ff' }
});
console.log(snippet);
// Outputs the full HTML snippet ready to copyReady to Embed?
Create an agent in your project, then grab the embed code from the agent settings.
