An embeddable chat widget that connects to webhook endpoints. Create beautiful chat interfaces powered by your custom workflows from n8n, Make.com, or any custom webhook provider.
- 🎨 Beautiful UI - Clean, fullscreen chat interface
- 🚀 Easy Integration - Single script tag or npm package
- đź’¬ Session Management - Automatic session handling
- đź’ľ Persistence - Optional localStorage support for chat history
- 🗂️ Thread Management - Create, switch, and delete conversation threads
- 🌓 Theme Support - Light and dark mode
- 📱 Responsive - Works perfectly on mobile and desktop
- 🔌 Provider Agnostic - Works with n8n, Make.com, or custom webhooks
Add this script to your HTML:
<link
href="https://cdn.jsdelivr.net/npm/genui-widget/dist/genui-widget.css"
rel="stylesheet"
/>
<script type="module">
import { createChat } from "https://cdn.jsdelivr.net/npm/genui-widget/dist/genui-widget.es.js";
createChat({
n8n: {
webhookUrl: "YOUR_WEBHOOK_URL",
},
agentName: "Assistant",
});
</script>See Quick Start above.
npm install genui-widgetNote: This package requires React 18 or 19 as peer dependencies. Make sure you have React installed in your project:
npm install react react-domimport { createChat } from "genui-widget";
const chat = createChat({
n8n: {
webhookUrl: "YOUR_WEBHOOK_URL",
},
});const chat = createChat({
// Required: Webhook configuration
n8n: {
webhookUrl: "https://your-webhook-endpoint.com/chat",
enableStreaming: false, // Optional: Enable streaming responses
},
// Optional settings
agentName: "Assistant", // Bot/agent name
logoUrl: "https://example.com/logo.png", // Logo image URL
theme: { mode: "light" }, // 'light' or 'dark'
storageType: "localstorage", // 'none' or 'localstorage'
mode: "fullscreen", // 'fullscreen' or 'sidepanel'
enableDebugLogging: false, // Enable console debug logging
// Optional: Callback when session starts
onSessionStart: (sessionId) => {
console.log("Session started:", sessionId);
},
});storageType: "none" (default):
- Messages work normally during the session
- All data is lost on page refresh
storageType: "localstorage":
- Chat conversations persist across page refreshes
- Users can create and manage multiple threads
- Thread history is saved to browser localStorage
// Get current session ID
const sessionId = chat.getSessionId();
// Open the chat window
chat.open();
// Close the chat window
chat.close();
// Destroy the widget completely
chat.destroy();The chat client sends POST requests to your webhook:
{
"chatInput": "User's message here",
"sessionId": "uuid-v4-session-id"
}Non-streaming mode:
{
"output": "Your bot's response here"
}Streaming mode (enableStreaming: true):
Return line-delimited JSON chunks:
{ "type": "item", "content": "First chunk " }
{ "type": "item", "content": "second chunk " }
{ "type": "item", "content": "final chunk" }
-
Create a Webhook Trigger
- Add a Webhook node to your workflow
- Set it to accept POST requests
- Note your webhook URL
-
Access the Data
- Message:
{{ $json.chatInput }} - Session ID:
{{ $json.sessionId }}
- Message:
-
Return a Response
- Use "Respond to Webhook" node
- Return:
{ "output": "Your response" }
-
Configure CORS
- Enable Domain Allowlist in webhook settings
- Add your domain(s):
example.com,www.example.com - For local dev:
localhost,127.0.0.1
Security Note: The webhook URL is visible in the browser. Use n8n's Domain Allowlist to restrict access.
- Create a scenario with a Webhook module
- Process
chatInputandsessionId - Add your logic (AI, database, etc.)
- Use Webhook Response to return
{ "output": "Your response" }
Your endpoint should:
- Accept POST requests with JSON body
- Parse
chatInputandsessionId - Return JSON:
{ "output": "Your response" }
For streaming, return line-delimited JSON chunks.
Complete list of all available options:
n8n: {
// Required: Your webhook URL
webhookUrl: string;
// Optional: Enable streaming responses (default: false)
enableStreaming?: boolean;
// Optional: Custom webhook configuration
webhookConfig?: {
method?: string; // HTTP method (default: "POST")
headers?: Record<string, string>; // Custom headers
};
}agentName?: string; // Default: "Assistant"The name displayed for the bot/agent in the chat interface.
logoUrl?: string;URL to a logo image that will be displayed in the chat interface.
enableDebugLogging?: boolean; // Default: falseEnable debug logging to the browser console. Useful for troubleshooting webhook integration issues.
theme?: {
mode: 'light' | 'dark'; // Default: 'light'
}Sets the color scheme for the chat interface.
storageType?: 'none' | 'localstorage'; // Default: 'none'Controls chat history persistence:
'none'- Messages are kept in memory only, lost on page refresh'localstorage'- Messages are saved to browser localStorage, persist across sessions
mode?: 'fullscreen' | 'sidepanel'; // Default: 'fullscreen'Controls the display mode:
'fullscreen'- Takes up the entire viewport'sidepanel'- Displays as a side panel (widget style)
onSessionStart?: (sessionId: string) => void;Callback function that fires when a new chat session is created. Receives the session ID as a parameter. Useful for analytics or tracking.
- Check browser console for errors
- Verify webhook URL is correct
- Ensure webhook endpoint is active and accessible
- Check CORS settings
- Verify webhook URL is correct
- Check CORS configuration
- Ensure your domain is allowlisted (for n8n)
- Verify response format:
{ "output": "message" } - Check webhook execution logs
- Node.js: Version 20.9.0 or higher (for development)
- Chrome/Edge (latest 2 versions)
- Firefox (latest 2 versions)
- Safari (latest 2 versions)
- Mobile browsers (iOS Safari, Chrome Mobile)
MIT
- GitHub Issues: Create an issue
- Documentation: View docs
Contributions are welcome! Please feel free to submit a Pull Request.