npm package: @nucodeai/n8n-embedded-chat-interface
Description: > Embeddable AI chat widget for n8n workflows. One script tag, works on any website.
Author: symbiosika
Latest version: 1.0.0

# n8n Embedded Chat Interface

> Embeddable AI chat widget for n8n workflows. One script tag, works on any website.

## Quick Start

```html
<script src="https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js"></script>
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/your-webhook-id/chat"
></n8n-embedded-chat-interface>
```

That's it. The chat widget appears as a floating bubble in the bottom-right corner.

## Installation

### CDN (Recommended)

**jsDelivr:**

```html
<script src="https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js"></script>
```

**unpkg:**

```html
<script src="https://unpkg.com/n8n-embedded-chat-interface@latest/output/index.js"></script>
```

### npm

```bash
npm install @nucodeai/n8n-embedded-chat-interface
```

Then import in your project:

```js
import '@nucodeai/n8n-embedded-chat-interface';
```

### Self-hosted

Build locally and serve `output/index.js` from your own server:

```bash
git clone https://github.com/symbiosika/n8n-embedded-chat-interface.git
cd n8n-embedded-chat-interface
npm install
npm run build
```

Then host the generated `output/index.js` on your server and reference it:

```html
<script src="https://your-server.com/path/to/index.js"></script>
```

## Configuration

All configuration is done via HTML attributes on the `<n8n-embedded-chat-interface>` element. No JavaScript required.

### Basic

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `hostname` | String | `""` | **Required.** Full URL of your n8n webhook endpoint. |
| `label` | String | `""` | Title displayed in the chat header. |
| `subtitle` | String | `""` | Subtitle shown below the title in the header. |
| `initial-message` | String | `""` | Welcome message from the bot shown when the chat opens. |
| `placeholder` | String | `""` | Placeholder text in the message input field. |
| `logo` | String | `""` | URL of an image displayed in the chat header (e.g., your company logo). |
| `mode` | String | `"n8n"` | Chat mode. Currently only `"n8n"` is supported. |
| `open-on-start` | String | `"false"` | Set to `"true"` to open the chat window automatically on page load. |
| `locale` | String | `"en"` | UI language. Supported: `en`, `de`, `es`. |
| `session-key` | String | `"n8n_chat_session"` | localStorage key used to persist the chat session ID. |

### Avatar & Branding

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `avatar` | String | `""` | URL of the image used for the floating chat bubble toggle. |
| `header-avatar` | String | `""` | URL of the avatar image shown in the chat header next to the title. |

### Bubble Toggle

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `bubble-size` | String | `"56"` | Size of the floating bubble in pixels. |
| `bubble-position` | String | `"bottom-right"` | Position of the bubble. Options: `"bottom-right"`, `"bottom-left"`. |
| `bubble-offset-x` | String | `"16"` | Horizontal offset from the edge in pixels. |
| `bubble-offset-y` | String | `"16"` | Vertical offset from the edge in pixels. |
| `bubble-border-radius` | String | `"50%"` | Border radius of the bubble. Use `"50%"` for circle, or pixel values. |

### Chat Window

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `window-width` | String | `"400"` | Width of the chat window in pixels. |
| `window-height` | String | `"600"` | Height of the chat window in pixels. |
| `window-border-radius` | String | `"16"` | Border radius of the chat window in pixels. |
| `window-shadow` | String | `"0 4px 24px rgba(0,0,0,0.12)"` | CSS box-shadow for the chat window. |
| `z-index` | String | `"9999"` | CSS z-index for the widget. |

### Typography

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `font-family` | String | `"inherit"` | CSS font-family for all text in the widget. |
| `font-size` | String | `"14"` | Base font size in pixels. |

### Colors

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| `primary-color` | String | — | Primary brand color. Used for buttons, toggle, send button. |
| `secondary-color` | String | — | Secondary accent color. |
| `background-color` | String | — | Background color of the chat window. |
| `text-color` | String | — | Main text color. |
| `accent-color` | String | — | Highlight and accent color. |
| `surface-color` | String | — | Surface/card background color (e.g., bot message bubbles). |
| `border-color` | String | — | Border color for the chat window and dividers. |
| `success-color` | String | — | Color for success states. |
| `warning-color` | String | — | Color for warning states. |
| `error-color` | String | — | Color for error states. |
| `bot-bubble-color` | String | — | Override background color for bot message bubbles. |
| `user-bubble-color` | String | — | Override background color for user message bubbles. |

Accepted color formats: hex (`#1a1a1a`), rgb (`rgb(26,26,26)`), hsl (`hsl(0,0%,10%)`), CSS named colors (`black`).

## Examples

### Minimal

```html
<script src="https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js"></script>
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/abc123/chat"
></n8n-embedded-chat-interface>
```

### Branded

```html
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/abc123/chat"
  label="Support"
  subtitle="We typically reply in seconds"
  logo="https://your-site.com/logo.png"
  avatar="https://your-site.com/avatar.jpg"
  header-avatar="https://your-site.com/avatar.jpg"
  initial-message="Hi there! How can I help you today?"
  primary-color="#2563eb"
  surface-color="#eff6ff"
  border-color="#bfdbfe"
></n8n-embedded-chat-interface>
```

### Bottom-Left Position

```html
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/abc123/chat"
  bubble-position="bottom-left"
  bubble-offset-x="24"
  bubble-offset-y="24"
></n8n-embedded-chat-interface>
```

### Full Customization

```html
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/abc123/chat"
  label="Acme Assistant"
  subtitle="AI-powered support"
  initial-message="Welcome to Acme Corp! Ask me anything about our products."
  placeholder="Type your question..."
  logo="https://acme.com/logo.svg"
  avatar="https://acme.com/bot-avatar.png"
  header-avatar="https://acme.com/bot-avatar.png"
  locale="en"
  open-on-start="false"
  session-key="acme_chat_session"
  bubble-size="64"
  bubble-position="bottom-right"
  bubble-offset-x="20"
  bubble-offset-y="20"
  bubble-border-radius="50%"
  window-width="420"
  window-height="640"
  window-border-radius="20"
  window-shadow="0 8px 32px rgba(0,0,0,0.16)"
  z-index="10000"
  font-family="Inter, sans-serif"
  font-size="15"
  primary-color="#6d28d9"
  secondary-color="#a78bfa"
  background-color="#ffffff"
  text-color="#1e1b4b"
  accent-color="#7c3aed"
  surface-color="#f5f3ff"
  border-color="#e9d5ff"
  success-color="#16a34a"
  warning-color="#ca8a04"
  error-color="#dc2626"
  bot-bubble-color="#f5f3ff"
  user-bubble-color="#6d28d9"
></n8n-embedded-chat-interface>
```

### Dark Theme

```html
<n8n-embedded-chat-interface
  hostname="https://your-n8n.com/webhook/abc123/chat"
  label="Night Owl"
  initial-message="Hello! How can I assist you?"
  primary-color="#818cf8"
  secondary-color="#6366f1"
  background-color="#0f172a"
  text-color="#e2e8f0"
  surface-color="#1e293b"
  border-color="#334155"
  bot-bubble-color="#1e293b"
  user-bubble-color="#4f46e5"
></n8n-embedded-chat-interface>
```

## WordPress Integration

### Option 1: HTML Block

In the Gutenberg editor, add a **Custom HTML** block and paste the full snippet (script tag + custom element).

### Option 2: Theme Footer

Add the following to your theme's `functions.php`:

```php
function enqueue_n8n_chat() {
    wp_enqueue_script(
        'n8n-chat',
        'https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js',
        [],
        '1.0.0',
        true
    );
    add_action('wp_footer', function() {
        echo '<n8n-embedded-chat-interface hostname="https://your-n8n.com/webhook/xxx/chat"></n8n-embedded-chat-interface>';
    });
}
add_action('wp_enqueue_scripts', 'enqueue_n8n_chat');
```

### Option 3: Plugin

Use a header/footer scripts plugin like **Insert Headers and Footers** (by WPCode) and paste the snippet into the footer scripts section. No code editing required.

## n8n Webhook API

### Request (widget -> n8n)

The widget sends a `POST` request to the URL specified in the `hostname` attribute:

```http
POST https://your-n8n.com/webhook/abc123/chat
Content-Type: application/json

{
  "chatInput": "Hello, I need help with my order",
  "sessionId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `chatInput` | String | The user's message. |
| `sessionId` | String | UUID identifying the conversation session. Persisted in localStorage. |

### Response (n8n -> widget)

The webhook must return JSON:

```json
{
  "output": "Your order #12345 has been shipped and will arrive by Friday.",
  "sessionId": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
}
```

| Field | Type | Description |
|-------|------|-------------|
| `output` | String | The bot's reply. Supports full **Markdown** (headings, lists, bold, links, code blocks). |
| `sessionId` | String | Session identifier. Returned by n8n to maintain conversation context. |

The widget also supports NDJSON streaming responses for advanced use cases.

## How It Works

- **Web Component** with Shadow DOM for complete CSS isolation from the host page
- **Vue 3 + TypeScript** under the hood, compiled to a single self-contained JS file
- **Single file bundle** (~300KB) with zero external runtime dependencies
- **Session persistence** via localStorage -- conversations survive page reloads
- **Markdown rendering** with [marked](https://github.com/markedjs/marked) + [DOMPurify](https://github.com/cure53/DOMPurify) for XSS-safe output
- **i18n** support: English (default), German, Spanish

## Development

### Setup

```bash
git clone https://github.com/symbiosika/n8n-embedded-chat-interface.git
cd n8n-embedded-chat-interface
npm install
```

### Development Server

```bash
npm run dev
```

Starts both the Vite dev server (with hot reload) and Tailwind CSS watcher in parallel. Open `http://localhost:5173/`.

### Build

```bash
npm run build
```

Compiles Tailwind CSS, runs TypeScript type checking, and produces the production bundle in `output/index.js`.

### Other Commands

| Command | Description |
|---------|-------------|
| `npm run format` | Format source code with Prettier. |
| `npm run type-check` | Run TypeScript type checking only. |
| `npm run preview` | Preview the production build locally. |
| `npm run demo` | Build and serve a demo at `http://localhost:8000/demo/`. |

### Architecture

```
src/
├── prod.ts                           # Production entry: defines <n8n-embedded-chat-interface> custom element
├── main.ts                           # Development entry: standard Vue app for testing
├── i18n.ts                           # Translations (en, de, es)
├── components/
│   ├── N8nEmbeddedChatInterface.vue  # Main widget: toggle bubble, header, chat window
│   ├── chat/n8n/Index.vue            # Chat UI: message bubbles, input, send
│   ├── Thinking.vue                  # Typing indicator (bouncing dots)
│   └── markdown/Renderer.vue         # Markdown rendering with DOMPurify
├── stores/
│   ├── App.ts                        # UI state: show/hide, config, defaults
│   └── n8n.ts                        # Chat state: messages, session, API calls
├── composables/
│   └── useCustomColors.ts            # Color validation and CSS variable generation
└── styles/
    ├── input.css                     # Tailwind CSS source
    └── output.css                    # Generated Tailwind CSS (inlined at build)
```

## Publishing to npm

```bash
npm run build
npm publish
```

After publishing, the package is automatically available at:

- **jsDelivr:** `https://cdn.jsdelivr.net/npm/n8n-embedded-chat-interface@VERSION/output/index.js`
- **unpkg:** `https://unpkg.com/n8n-embedded-chat-interface@VERSION/output/index.js`

Replace `VERSION` with the version number (e.g., `1.0.0`) or use `latest`.

## Security

### Built-in protections

- **Shadow DOM isolation** — widget styles and DOM are fully encapsulated; no CSS leakage to/from the host page
- **DOMPurify** — all markdown in bot responses is sanitized before rendering (XSS-safe)
- **CSS injection prevention** — all color, dimension, and URL attributes are validated with strict patterns
- **Rate limiting** — client-side throttle (1 message/second) prevents accidental spam
- **Message length limit** — 2000 character maximum prevents payload abuse
- **Request timeout** — 30s AbortController timeout prevents hung UI
- **Sanitized errors** — error messages never expose webhook URLs or internal details

### Recommendations for production

**Always pin the version and use SRI (Subresource Integrity):**

```html
<script
  src="https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js"
  integrity="sha384-HASH_HERE"
  crossorigin="anonymous"
></script>
```

Generate the SRI hash after publishing:
```bash
curl -s https://cdn.jsdelivr.net/npm/@nucodeai/n8n-embedded-chat-interface@1.0.0/output/index.js | openssl dgst -sha384 -binary | openssl base64 -A
```

**Secure your n8n webhook:**
- Enable authentication (API key or Bearer token) on your n8n webhook node
- Configure CORS to only allow your specific domains
- Add rate limiting at the n8n/server level
- Use HTTPS for all webhook URLs

**Content Security Policy (CSP):**

If your site uses CSP headers, ensure the following directives:
```
script-src 'self' https://cdn.jsdelivr.net;
style-src 'unsafe-inline';
connect-src https://your-n8n-domain.com;
```

## Browser Support

| Browser | Minimum Version |
|---------|----------------|
| Chrome | 67+ |
| Firefox | 63+ |
| Safari | 10.1+ |
| Edge | 79+ |

Requires support for Custom Elements v1 and Shadow DOM v1.

## Migration from 0.4.x

If upgrading from version 0.4.x, note the following breaking changes:

- **Default locale** changed from `"es"` to `"en"`. Set `locale="es"` to keep Spanish.
- **Default avatar** changed from a built-in image to a generic chat icon. Set `avatar="https://..."` for a custom image.
- **Session storage key** changed from `"uniq_chat_session"` to `"n8n_chat_session"`. Set `session-key="uniq_chat_session"` to preserve existing sessions.
- **CSS is now inlined** in the JS bundle. No separate CSS file is needed.

## License

[Apache-2.0](https://www.apache.org/licenses/LICENSE-2.0)