@orga-ai/widget
v0.0.1
Published
Widget SDK for Orga AI — real-time multimodal AI that hears, sees, and speaks.
Downloads
73
Readme
Orga AI Widget SDK
TypeScript-first widget SDK for Orga AI. It lets you embed a multimodal voice & video assistant either via:
- CDN snippet – drop two
<script>tags into any site and configure a globalOrgaWidget. - NPM package import – install
@orga-ai/widgetand call a typedinitWidgethelper from React/TypeScript.
This package is built on top of @orga-ai/react and expects you to provide a backend that exchanges your Orga API key for short‑lived session credentials.
Installation (npm / pnpm / yarn)
The widget package is published as @orga-ai/widget:
pnpm add @orga-ai/widget
# or
npm install @orga-ai/widget
# or
yarn add @orga-ai/widgetYou will also need:
@orga-ai/react@orga-ai/core
Those are declared as dependencies/peer dependencies of this package.
Backend requirements
The widget never receives your Orga API key directly. Instead, you expose a backend endpoint that returns a session configuration object:
type SessionConfigResponse = {
ephemeralToken: string;
iceServers: Array<{
urls: string | string[];
username?: string;
credential?: string;
}>;
};At minimum, your backend must:
- Hold your Orga API key securely (environment variable or secret store).
- Call Orga to create a session.
- Return
{ ephemeralToken, iceServers }JSON to the frontend.
You can do this with @orga-ai/node or any HTTP client that talks to Orga.
CDN usage
Use this when you want the simplest integration: static sites, CMS, marketing pages, or anywhere you can edit HTML and host a tiny backend.
1. Include the widget bundle
Add the CDN script to your page (replace the URL with your actual CDN endpoint if different):
<!-- Load the Orga AI widget from the CDN -->
<script src="https://widget-test-inky-one.vercel.app/init.global.js" async></script>2. Initialize the widget
After the CDN script loads, a global OrgaWidget object is available on window. Call OrgaWidget.initWidget with your configuration:
<script>
OrgaWidget.initWidget({
// Required: fetch session credentials from your backend
fetchSessionConfig: () =>
fetch("https://your-backend.example.com/api/orga-session").then((res) =>
res.json(),
),
// Optional: label for logging / error messages
sessionConfigEndpoint: "https://your-backend.example.com/api/orga-session",
// Optional: override default voice and logging
voice: "fable",
logLevel: "info",
// Optional: layout & UI configuration (see full table below)
theme: "floating-badge",
transcript: "panel",
videoPreview: "optional",
branding: {
brandName: "Orga Assistant",
tagline: "Your realtime copilot",
accentColor: "#2D9FBC",
},
});
</script>3. Add a mount point
By default, the widget will mount into the first element that matches [data-orga-widget]. Add that to your HTML where you want the widget shell to live:
<div data-orga-widget></div>You can also pass a specific target (selector or element) via initWidget({ target }).
React / Next.js usage (import)
Use this when you want full TypeScript tooling and React integration. The API is the same as the CDN global but imported from the package.
1. Import and initialize
In a React/Next.js app, create a small client component that calls initWidget once on mount:
"use client";
import { useEffect } from "react";
import { initWidget, type WidgetInitOptions } from "@orga-ai/widget";
export const OrgaWidgetClient = (): JSX.Element => {
useEffect(() => {
const options: WidgetInitOptions = {
fetchSessionConfig: () =>
fetch("/api/orga-session").then((res) => res.json()),
theme: "floating-badge",
transcript: "panel",
videoPreview: "optional",
branding: {
brandName: "Orga Assistant",
tagline: "Your realtime copilot",
},
};
initWidget(options);
}, []);
return <div data-orga-widget />;
};2. Add it to your layout for global availability
In the Next.js App Router, render the widget once in your root layout so it persists across client‑side navigation:
// app/layout.tsx
import type { Metadata } from "next";
import { OrgaWidgetClient } from "./components/OrgaWidgetClient";
export const metadata: Metadata = {
title: "Orga AI Widget Example",
description: "Demo of the @orga-ai/widget SDK",
};
export default function RootLayout(props: { children: React.ReactNode }): JSX.Element {
const { children } = props;
return (
<html lang="en">
<body>
{children}
<OrgaWidgetClient />
</body>
</html>
);
}3. Use client‑side navigation to preserve sessions
Because the widget and session are tied to the current page, full reloads will reset them. In Next.js, use next/link rather than raw <a> tags to navigate without tearing down the layout:
"use client";
import Link from "next/link";
export const PageLinks = (): JSX.Element => {
return (
<div className="flex gap-4">
<Link href="/test" className="btn">
Test Page
</Link>
<Link href="/another" className="btn">
Another Page
</Link>
</div>
);
};As long as OrgaWidgetClient lives in a layout that does not unmount during navigation, the widget can keep an active session while the user browses the app.
initWidget API reference
The main entry point for both CDN and import usage is:
initWidget(options: WidgetInitOptions): void;WidgetInitOptions
export type WidgetInitOptions = {
/**
* HTMLElement or selector that will host the widget UI.
* Defaults to the first element with `[data-orga-widget]`.
*/
target?: HTMLElement | string;
/**
* Function that returns the session configuration (ephemeral token + ICE servers).
* Mirrors the existing React SDK requirement so we can reuse backends.
*/
fetchSessionConfig: () => Promise<SessionConfigResponse>;
/**
* Optional session configuration endpoint to seed OrgaAI.init.
* Used only for logging / diagnostics.
*/
sessionConfigEndpoint?: string;
/**
* Optional voice/model configuration to seed OrgaAI.init.
*/
voice?: OrgaAIVoice;
/**
* Logging verbosity override.
*/
logLevel?: "disabled" | "error" | "warn" | "info" | "debug";
/**
* Theme/layout preset for the widget shell.
*/
theme?: WidgetThemeName;
/**
* Controls whether the transcript panel is visible.
*/
transcript?: TranscriptMode;
/**
* Controls camera preview behavior.
*/
videoPreview?: VideoPreviewMode;
/**
* UI branding: name, tagline, and color palette.
*/
branding?: Partial<WidgetBranding>;
};Options table
| Option | Type | Required | Default | Description |
| ----------------------- | --------------------------------------------------- | -------- | ----------------------- | ----------- |
| target | HTMLElement \| string | No | First [data-orga-widget] | DOM element or CSS selector where the widget shell is mounted. |
| fetchSessionConfig | () => Promise<SessionConfigResponse> | Yes | – | Async function that calls your backend and returns { ephemeralToken, iceServers }. |
| sessionConfigEndpoint | string | No | undefined | Human‑readable endpoint label for logging and error messages. |
| voice | OrgaAIVoice | No | "fable" | Default voice/model to use for the session. |
| logLevel | "disabled" \| "error" \| "warn" \| "info" \| "debug" | No | "info" | Controls internal logging verbosity. |
| theme | WidgetThemeName | No | "floating-badge" | Layout preset for the widget shell. |
| transcript | TranscriptMode | No | "panel" | Whether to show the transcript panel. |
| videoPreview | VideoPreviewMode | No | "optional" | Controls camera preview and toggle behavior. |
| branding | Partial<WidgetBranding> | No | See below | Branding configuration (merged with safe defaults). |
UI configuration (theme, transcript, video, branding)
export type WidgetThemeName = "floating-badge" | "panel" | "full";
export type TranscriptMode = "hidden" | "panel";
export type VideoPreviewMode = "hidden" | "optional" | "always";
export type WidgetBranding = {
brandName: string;
tagline?: string;
accentColor: string;
backgroundColor: string;
borderColor: string;
textColor: string;
secondaryTextColor: string;
badgeIconUrl?: string;
logoUrl?: string;
logoAlt?: string;
};
export type WidgetFeatureConfig = {
transcript: TranscriptMode;
videoPreview: VideoPreviewMode;
};Defaults
At runtime, the widget merges your visual options with safe defaults:
const DEFAULT_BRANDING: WidgetBranding = {
brandName: "Orga Assistant",
tagline: "Your realtime copilot",
accentColor: "#2D9FBC",
backgroundColor: "#ffffff",
borderColor: "#e2e8f0",
textColor: "#0f172a",
secondaryTextColor: "#475569",
};
const DEFAULT_FEATURES: WidgetFeatureConfig = {
transcript: "panel",
videoPreview: "optional",
};
// theme default:
const defaultTheme: WidgetThemeName = "floating-badge";UI options table
theme
| Value | Description |
| ----------------- | ----------- |
| "floating-badge" | Widget appears as a docked badge in the corner that expands into a panel. |
| "panel" | Widget renders as a panel at the point where you place the host element. |
| "full" | Large, full‑panel experience intended for dedicated assistant pages. |
branding
All branding fields are optional when passed via branding; they are merged with DEFAULT_BRANDING and sanitized.
| Field | Type | Default | Notes |
| --------------------- | -------- | ------------------------ | ----- |
| brandName | string | "Orga Assistant" | Product or company name shown in the header. |
| tagline | string | "Your realtime copilot" | Short subtitle beneath the brand name. |
| accentColor | string | "#2D9FBC" | Main accent color used for buttons and badge. |
| backgroundColor | string | "#ffffff" | Widget body background. |
| borderColor | string | "#e2e8f0" | Border color for panels and transcript boxes. |
| textColor | string | "#0f172a" | Primary text color. |
| secondaryTextColor | string | "#475569" | Secondary / muted text. |
| badgeIconUrl | string | Orga logo data URI | URL or data:image/* URI for the floating badge icon. Non‑HTTPS URLs are ignored. |
| logoUrl | string | undefined | Optional logo shown in the header. Non‑HTTPS URLs are ignored. |
| logoAlt | string | brandName | alt text for the header logo. |
Visual style guide (status badge & buttons)
The widget exposes a small set of CSS variables so you can align it with your brand while keeping a sensible, accessible default:
Colors derived from
brandingaccentColor→--orga-widget-accent(floating badge background, primary button, user bubbles, “connecting” status).backgroundColor→--orga-widget-bg(panel and transcript background).borderColor→--orga-widget-border(panel, transcript, outline buttons).textColor→--orga-widget-primary(primary text, outline button text).secondaryTextColor→--orga-widget-secondary(status default text, hints, subtitles).
Status badge tokens
--orga-widget-status-radius(default999px): pill shape for the status chip.--orga-widget-status-default-bg/--orga-widget-status-default-text: idle/neutral state colors.--orga-widget-status-connected-bg/--orga-widget-status-connected-text: “Connected” state.--orga-widget-status-connecting-bg/--orga-widget-status-connecting-text: “Connecting” state that tints toward youraccentColor.
Button tokens
--orga-widget-control-radius(default999px): shared radius for all CTA buttons.--orga-widget-button-primary-bg/--orga-widget-button-primary-text: main “Start session” CTA, defaults to youraccentColoron white text.--orga-widget-button-danger-bg/--orga-widget-button-danger-text: destructive “Disconnect” CTA, defaults to the error color.--orga-widget-button-outline-border/--orga-widget-button-outline-text: outline buttons (mic/camera), defaulting to your border/text colors.
In most cases, setting branding.accentColor, branding.backgroundColor, branding.borderColor, and the two text colors is enough to get a cohesive look. Advanced teams can override the CSS variables above in their own stylesheet to further tune badge/button shapes or color ramps while still relying on the same semantic tokens.
features
| Field | Type | Default | Description |
| -------------- | ---------------------------------- | ----------- | ----------- |
| transcript | "hidden" | "panel" | "panel" | Whether to show a live transcript panel. |
| videoPreview | "hidden" | "optional" | "always" | "optional" | Controls the camera preview and video toggle button. |
Error handling and safety
The widget wraps your fetchSessionConfig with a safety helper that:
- Enforces secure contexts (HTTPS or
localhost) for media access. - Applies a timeout and small retry policy.
- Validates that the session config payload contains the required fields.
In case of issues, the user sees clear UI feedback instead of a permanently spinning widget, and the console includes descriptive messages to help you debug misconfigured backends.
Notes
- The CDN usage in plain HTML does not provide TypeScript IntelliSense in your editor because it lives outside your TS project.
- For full type safety and autocomplete, prefer the import usage (
import { initWidget, type WidgetInitOptions } from "@orga-ai/widget") in a TypeScript/React app. - Both integration styles share the same underlying
initWidgetsurface, so you can document them together and migrate between them without changing backend behavior.
