@8wave/ai-elements
v0.54.0
Published
A framework-agnostic Web Component that embeds a floating AI chat widget into any webpage. Built with Vue 3 and distributed as a standard Custom Element — no framework dependency required on the consumer side.
Readme
@8wave/ai-elements
A framework-agnostic Web Component that embeds a floating AI chat widget into any webpage. Built with Vue 3 and distributed as a standard Custom Element — no framework dependency required on the consumer side.
Overview
The package exposes a single custom element, <floating-chat-widget>, that renders a fixed-position button in the bottom-right corner of the page. Clicking the button opens a full chat interface powered by the 8wave AI backend. Anonymous authentication is handled automatically by the component.
Installation
npm install @8wave/ai-elements
# or
pnpm add @8wave/ai-elementsUsage
Via npm package
Import the package once (e.g. in your app entry point). The custom element registers itself automatically.
import '@8wave/ai-elements'Then use the element anywhere in your HTML:
<floating-chat-widget
organization-slug="your-org-slug"
agent-id="your-agent-id"
></floating-chat-widget>Via CDN (no bundler)
<!-- unpkg -->
<script type="module" async src="https://unpkg.com/@8wave/ai-elements"></script>
<!-- or jsDelivr -->
<!-- <script type="module" async src="https://cdn.jsdelivr.net/npm/@8wave/ai-elements"></script> -->
<floating-chat-widget
organization-slug="your-org-slug"
agent-id="your-agent-id"
></floating-chat-widget>Attributes
| Attribute | Type | Required | Default | Description |
| ------------------- | -------- | -------- | ------------------------- | ------------------------------------------------------------ |
| agent-id | string | ✅ | — | The unique identifier of the AI agent to connect to. |
| organization-slug | string | ✅ | — | The slug of the organization that owns the agent. |
| prefix-url | string | ❌ | VITE_BACKEND_URL (build-time) | Base URL of the 8wave backend API. Override this when self-hosting or pointing to a different environment. |
How it works
- On mount the component automatically signs in as an anonymous user via the 8wave Auth service.
- Once authenticated it fetches the agent configuration (name, interface colors, etc.) from the public API.
- A circular floating button appears in the bottom-right corner, styled with the agent's
mainColor. - Clicking the button toggles the chat panel open/closed.
- All styles are encapsulated inside a Shadow DOM — no CSS leaks in or out.
Development
# install dependencies (from the monorepo root)
pnpm install
# start the dev server (port 8082)
pnpm nx run web-component:dev
# build the library bundle
pnpm nx run web-component:buildThe dev server mounts the component against a real backend using the credentials configured in your local .env file.
Build output
| File | Format | Description |
| -------------------------------- | ------ | ------------------------ |
| dist/floating-chat-widget.es.js | ESM | For bundlers / import |
| dist/floating-chat-widget.umd.js | UMD | For CDN / require |
CSS is injected directly into the Shadow DOM by the JavaScript bundle — no separate stylesheet needs to be loaded.
Vue Components
In addition to the web component, the package exposes all Pk* Vue 3 components for direct use inside Vue applications.
Installation
pnpm add @8wave/ai-elements vue vue-i18n @volverjs/ui-vueSetup
The components require vue-i18n to be installed and configured in the host application. They call useI18n({ useScope: 'global' }) internally, so the i18n instance must be registered via app.use(i18n) before mounting any component.
// main.ts
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import '@8wave/ai-elements/vue/style.css'
import App from './App.vue'
const i18n = createI18n({
legacy: false,
locale: 'it',
messages: {
it: { /* your translations */ },
en: { /* your translations */ },
},
})
createApp(App).use(i18n).mount('#app')Note:
@volverjs/ui-vuemust also be registered viaapp.use(VolverPlugin, { ... })with the icon collections and any component defaults you need.
Usage
import { PkChatbot } from '@8wave/ai-elements/vue'<PkChatbot
api="https://api.example.com"
agent-id="your-agent-id"
v-model:chat-id="chatId"
:headers="{ Authorization: `Bearer ${token}` }"
:actions="['upvote', 'downvote', 'copy']"
system-theme="light"
@error="handleError"
/>PkChatbot props
| Prop | Type | Required | Description |
| --------------- | ---------------------------- | -------- | -------------------------------------------------------------- |
| api | string | ✅ | Base URL of the 8wave backend API. |
| agentId | string | ✅ | Unique identifier of the AI agent. |
| agentType | 'chat' \| 'reasoning' | ❌ | Enables reasoning mode (hides feedback actions). |
| userId | string | ❌ | Optional user identifier forwarded to the backend. |
| name | string | ❌ | Display name shown in the chat header. |
| model | string | ❌ | Override the default language model. |
| agentModel | AgentModel | ❌ | Full model configuration object. |
| agentTools | AgentTools | ❌ | Tool configuration exposed to the agent. |
| agentInterface| AgentInterface | ❌ | Interface customization (colors, placeholder text, etc.). |
| actions | ChatMessageActions[] | ❌ | Actions available on each message ('upvote', 'downvote', 'copy', 'feedback', …). |
| revisedAnswers| RevisedAnswer[] | ❌ | List of revised answers to display inline. |
| headers | Record<string, string> | ❌ | Extra HTTP headers forwarded to every API request. |
| systemTheme | 'light' \| 'dark' | ❌ | Override the OS color scheme preference. |
PkChatbot v-model
| Model | Type | Description |
| --------- | --------------------- | ------------------------------------------------- |
| chatId | string \| undefined | Two-way binding for the active conversation ID. |
PkChatbot events
| Event | Payload | Description |
| ---------------- | ---------------------------------------------------- | ---------------------------------------- |
| message-update | UIChatMessage | Emitted whenever a message is updated. |
| show-info | UIChatMessage | User requested info panel for a message. |
| revise | UIChatMessage | User requested answer revision. |
| error | { type: string; title: string; status: number } | A transport or API error occurred. |
Available components
| Component | Description |
| ------------------------------- | -------------------------------------------------------- |
| PkChatbot | Main chatbot component — use this as your entry point. |
| PkChatbotMessages | Scrollable message list. |
| PkChatbotInput | Chat input bar with file/audio support. |
| PkChatbotError | Error state display. |
| PkChatbotFeedbackForm | Feedback collection form. |
| PkChatbotViewChat | Full chat view (messages + input). |
| PkChatbotViewConversations | Conversation history list. |
| PkChatbotViewProfile | User profile view. |
Import the stylesheet once in your app entry point:
import '@8wave/ai-elements/vue/style.css'Available composables
All composables are exported from @8wave/ai-elements/vue.
useAuth(options?)
Creates a better-auth client pre-configured to talk to the 8wave backend. Handles Bearer token injection and stores the session token in a first-party cookie automatically.
import { useAuth } from '@8wave/ai-elements/vue'
const auth = useAuth({ baseURL: 'https://api.example.com' })
await auth.signIn.anonymous()| Option | Type | Required | Description |
| --------- | -------- | -------- | ------------------------------------------------------------------------ |
| baseURL | string | ❌ | Base URL of the 8wave backend. Defaults to the VITE_BACKEND_URL build-time env variable. |
authToken
A reactive computed ref that reads/writes the current session token from/to the first-party cookie (eight-wave-ai).
import { authToken } from '@8wave/ai-elements/vue'
// Read
console.log(authToken.value)
// Write (also persists to cookie)
authToken.value = 'new-token'Available utilities
All utilities are exported from @8wave/ai-elements/vue.
setSessionCookie(token)
Writes the session token to a first-party Secure; SameSite=Lax cookie named eight-wave-ai with a 1-year expiry.
getSessionCookie()
Reads and returns the current value of the eight-wave-ai session cookie, or an empty string if it is not set.
