iris-widget
v1.0.1
Published
Embeddable IRIS AI chat widget for React apps — powered by Nuqi Wealth
Downloads
249
Readme
iris-widget
Embeddable IRIS AI chat widget for React apps — powered by Nuqi Wealth.
Installation
npm install iris-widgetQuick Start
Wrap your app (or a section of it) with IrisWidget, then drop IrisChat wherever you want the widget to appear.
import { IrisWidget, IrisChat } from 'iris-widget'
import 'iris-widget/styles.css'
function App() {
return (
<IrisWidget clientId="your-client-id" apiKey="your-api-key">
<IrisChat />
</IrisWidget>
)
}Authentication
There are three auth modes — pick the one that fits your setup.
B2B (client-side credentials)
Pass clientId and apiKey directly. Credentials are sent from the browser.
<IrisWidget clientId="cli_live_..." apiKey="nwdbx_live_...">
{children}
</IrisWidget>Proxy auth (recommended for production)
Your reverse proxy injects x-client-id and x-api-key headers before forwarding requests to the IRIS API. No credentials are ever exposed to the browser.
<IrisWidget proxyAuth irisBaseUrl="https://your-proxy.example.com/iris">
{children}
</IrisWidget>Legacy JWT
Pass a pre-obtained IRIS JWT directly, or a Nuqi user JWT which the widget exchanges for an IRIS token automatically.
// Direct IRIS JWT
<IrisWidget irisToken="eyJ...">
{children}
</IrisWidget>
// Nuqi user JWT (exchanged via POST /auth/nuqiwealth/login)
<IrisWidget userToken={nuqiUserJwt}>
{children}
</IrisWidget>IrisWidget Props
| Prop | Type | Default | Description |
|---|---|---|---|
| clientId | string | — | B2B client ID |
| apiKey | string | — | B2B API key |
| proxyAuth | boolean | false | Use proxy auth mode |
| chatMode | 'session' \| 'sessionless' | 'session' | session persists history in DB; sessionless resets on page refresh |
| irisToken | string | — | Pre-obtained IRIS JWT |
| userToken | string | — | Nuqi user JWT for token exchange |
| irisBaseUrl | string | IRIS production URL | Override the IRIS API base URL |
| theme | IrisThemeProp | 'dark' | Built-in theme name or custom ThemeConfig object |
| onError | (err: IrisError) => void | — | Called on auth errors |
| className | string | — | Class added to the root div |
| style | CSSProperties | — | Inline style on the root div |
IrisChat Props
| Prop | Type | Default | Description |
|---|---|---|---|
| mode | 'floating' \| 'inline' \| 'drawer' \| 'modal' \| 'docked' | 'floating' | How the chat panel is rendered |
| position | 'bottom-right' \| 'bottom-left' | 'bottom-right' | Bubble position (floating / drawer / modal) |
| height | number | 600 | Panel height in px |
| width | number | 420 | Panel width in px |
| suggestedQueries | string[] | [] | Prompt chips shown on an empty conversation |
| placeholder | string | — | Input placeholder text |
| className | string | — | Extra class on the wrapper |
| style | CSSProperties | — | Inline style on the wrapper |
Display modes
| Mode | Behaviour |
|---|---|
| floating | Bubble in corner; panel slides in above it |
| inline | Panel rendered directly in the DOM at fixed width × height |
| drawer | Panel slides in from the side with a backdrop |
| modal | Centred overlay with a backdrop |
| docked | Panel anchored to the edge; toggled by a fixed tab |
Theming
Built-in themes
dark · light · ocean · midnight · sand · carbon
<IrisWidget theme="ocean" ...>Custom theme
Pass a partial ThemeConfig object — any omitted keys fall back to the dark defaults.
<IrisWidget
theme={{
bgPrimary: '#0a0a0a',
accent: '#f59e0b',
accentDark: '#d97706',
}}
...
>ThemeConfig keys
| Key | CSS variable | Description |
|---|---|---|
| bgPrimary | --iris-bg | Main background |
| bgSurface | --iris-surface | Surface background |
| bgCard | --iris-card | Card / message background |
| bgInput | --iris-input | Input field background |
| textPrimary | --iris-text | Primary text colour |
| textSecondary | --iris-text-secondary | Secondary text colour |
| textMuted | --iris-text-muted | Muted / placeholder text |
| accent | --iris-accent | Accent colour (buttons, highlights) |
| accentDark | --iris-accent-dark | Darker accent (hover states) |
| accentDim | --iris-accent-dim | Translucent accent (backgrounds) |
| border | --iris-border | Default border colour |
| borderStrong | --iris-border-strong | Strong border colour |
| userBubbleBg | --iris-user-bubble | User message bubble background |
| userBubbleText | --iris-user-text | User message bubble text colour |
useIris Hook
Access the IRIS context from any component inside IrisWidget.
import { useIris } from 'iris-widget'
function Status() {
const { isReady, isAuthenticated, isAuthError } = useIris()
if (!isReady) return <p>Connecting…</p>
if (isAuthError) return <p>Auth failed</p>
if (!isAuthenticated) return <p>Not authenticated</p>
return <p>Ready</p>
}CSS
Import the stylesheet once at your app root:
import 'iris-widget/styles.css'Examples
Floating bubble (default)
<IrisWidget clientId="..." apiKey="...">
<IrisChat
mode="floating"
position="bottom-right"
suggestedQueries={['What is my portfolio value?', 'Show me top ETFs']}
/>
</IrisWidget>Inline panel
<IrisWidget clientId="..." apiKey="...">
<div style={{ width: 420, height: 600 }}>
<IrisChat mode="inline" />
</div>
</IrisWidget>Proxy auth with custom theme
<IrisWidget
proxyAuth
irisBaseUrl="/api/iris"
theme="midnight"
chatMode="session"
onError={(err) => console.error(err.code, err.message)}
>
<IrisChat mode="drawer" width={480} />
</IrisWidget>