Required for managed mode. Config is loaded from server. Also enables analytics and domain whitelisting.
Click + to add a service to your widget.
Display a text label next to the chat button
Upgrade to a paid plan to remove the attribution notice.
Click "Preview Widget" to see your widget
Get your AI chat widget up and running in 3 simple steps:
Build an AI chat workflow in n8n with a Webhook trigger, AI Agent with your knowledge base, and optionally connect an InfraNodus expert graph for enhanced responses.
Use the Widget Builder tab to create your widget. Choose Self-Hosted for simple popup/inline embed, or Managed for URL/iFrame sharing and analytics.
Copy the embed code into your website, or share the direct URL with your users. The widget connects to your n8n workflow automatically.
Add this code to your website with all settings inline:
<script src="__WIDGET_URL__"></script>
<script> new N8NWidget({ webhookUrl:
'https://your-n8n.com/webhook/xxx', title: 'Chat with us',
primaryColor: '#0084ff' }); </script>
Load configuration from server - update settings without changing embed code:
<script src="__WIDGET_URL__"></script>
<script> new N8NWidget({ apiKey: 'your-api-key' });
</script>
Embed the widget inside a specific container on your page:
<div id="n8n-chat-widget-container" style="height:
600px;"></div> <script> new N8NWidget({ mode:
'embed', targetElement: '#n8n-chat-widget-container',
webhookUrl: 'https://your-n8n.com/webhook/xxx' });
</script>
Use an iframe for sandboxed environments or easy integration:
<iframe
src="https://your-domain.com/widget-embed.html?id=YOUR_WIDGET_ID"
style="width: 400px; height: 600px; border: none;">
</iframe>
For React applications, use this useEffect hook to dynamically load and initialize the widget:
useEffect(() => { // Load N8N widget script dynamically const
script = document.createElement('script') script.src =
'https://n8n-chat-widget.com/widget.min.js' script.async =
true script.onload = () => { if (typeof window.N8NWidget !==
'undefined') { new window.N8NWidget({ // For self-hosted mode:
webhookUrl: 'https://your-n8n.com/webhook/xxx', title: 'Chat
with us', primaryColor: '#0084ff' // Or for managed mode: //
apiKey: 'your-api-key', // widgetId: 'your-widget-id' }) } }
document.head.appendChild(script) return () => { // Cleanup:
remove script if component unmounts if
(document.head.contains(script)) {
document.head.removeChild(script) } } }, [])
Tip: You can also create a custom React component wrapper for reusability across your application.
new N8NWidget({ webhookUrl:
'https://your-n8n.com/webhook/support', title: 'Support',
subtitle: 'How can we help?', primaryColor: '#10b981'
});
new N8NWidget({ webhookUrl:
'https://your-n8n.com/webhook/sales', title: 'Sales Team',
subtitle: 'Get a free quote', primaryColor: '#8b5cf6',
requireEmail: true, requireName: true, welcomeMessage: 'Hi!
Looking for a quote? Let me help you.', autoOpen: true,
openDelay: 5000 });
Your n8n webhook receives this data when a message is sent:
{ "message": "User's message text", "sessionId":
"session-abc123", "timestamp": "2024-01-01T12:00:00.000Z",
"url": "https://yoursite.com/page", "userName": "John Doe",
"userEmail": "john@example.com" }
Return a response in any of these formats:
// JSON response { "message": "Thanks for your message!" } //
Alternative fields also work: { "output": "..." } {
"response": "..." } { "text": "..." }
Control the widget from your JavaScript code:
const widget = new N8NWidget({ ... }); widget.open(); // Open
the chat widget.close(); // Close the chat widget.toggle(); //
Toggle open/close widget.destroy(); // Remove the widget
| Parameter | Type | Default | Description |
|---|---|---|---|
webhookUrl |
string | '' | N8N webhook URL for message handling |
mode |
string | 'popup' | Widget mode: 'popup', 'popup-multiple', or 'embed' |
popupOptions |
array | [] | Popup options for multi-option mode. |
multiOptionPrompt |
string | 'How would you like to connect?' | Header text for multi-option popup. |
targetElement |
string | null | CSS selector for embed container |
| Parameter | Type | Default | Description |
|---|---|---|---|
title |
string | 'Chat with us' | Widget header title |
subtitle |
string | 'We typically reply...' | Widget header subtitle |
primaryColor |
string | '#0084ff' | Primary theme color |
textColor |
string | '#ffffff' | Header text color |
backgroundColor |
string | '#ffffff' | Widget background color |
width |
string | '380px' | Widget width |
height |
string | '600px' | Widget height |
| Parameter | Type | Default | Description |
|---|---|---|---|
buttonPosition |
string | 'bottom-right' | Button position on screen |
buttonSize |
number | 60 | Button size in pixels |
buttonIcon |
string | '💬' | Button icon (emoji or text) |
buttonText |
string | '' | Optional button text |
| Parameter | Type | Default | Description |
|---|---|---|---|
autoOpen |
boolean | false | Auto-open widget on page load |
openDelay |
number | 0 | Delay before auto-open (ms) |
persistMessages |
boolean | true | Save messages in localStorage |
showTimestamps |
boolean | true | Display message timestamps |
requireEmail |
boolean | false | Require email before chat |
requireName |
boolean | false | Require name before chat |
hideAttribution |
boolean | false | Hide "Powered by Nodus Labs" notice (paid plans only) |
| Parameter | Type | Default | Description |
|---|---|---|---|
welcomeMessage |
string | 'Hello! How can...' | Initial bot message |
placeholder |
string | 'Type your message...' | Input placeholder text |
offlineMessage |
string | 'We are currently...' | Offline status message |
errorMessage |
string | 'Something went wrong...' | Error message |
Save your widget first to view analytics.