Quick Start

Add your AI persona to any website with a single embed code. Replace YOUR_PERSONA_ID with your persona ID from the dashboard.

<div id="my-persona" style="width:400px;height:600px;"></div>
<script src="https://cdn.personaizer.com/widget.js#loader#YOUR_PERSONA_ID#my-persona"></script>

The div is required — the widget renders into it. Style with CSS to set size.

Global State

These globals are set by widget.js and can be read at any time.

VariableTypeDescription
window.PersonAIzerLoadProgressnumberLoading progress from 0 to 1.
window.PersonAIzerIsLoadedbooleanWhether the Unity instance has loaded.
window.PersonAIzerLoadErrorstring | nullError message if loading failed.
window.PersonAIzerUnityInstanceUnityInstanceThe Unity WebGL instance (advanced use).

Setup

Set callbacks on window.PersonAIzer before loading widget.js. After the widget loads, call methods on the same object.

// Set callbacks before loading the widget
window.PersonAIzer = {
  onAppStateChanged: (state) => {
    console.log("State:", state);
    if (state === "live") {
      // Persona is ready for conversation
    }
  },
  onChatUpdated: (msg) => {
    console.log(msg.Author + ": " + msg.Message);
  }
};

// After widget loads, call methods:
// PersonAIzer.sendSystemMessage("Hello!");
// PersonAIzer.setTheme("dark");

End User ID: widget.js automatically generates and persists a stable user ID in localStorage. To provide your own, set window.PERSONAIZER_END_USER_ID before loading widget.js.

Methods

All methods are available on window.PersonAIzer after the widget loads. Check getAppState() is "live" before calling interaction methods.

State
getAppState()"loading" | "queue" | "initializing" | "standby" | "consent" | "live" | "error"

Returns the current lifecycle state of the widget.

startSession()void

Kick off the backend session from a user gesture (click/tap). Fires POST /api/sessions/start, opens the WebSocket, and unlocks audio in the same gesture. Required first call once appState === "loading" and the engine is ready — until then no backend traffic happens.

exitStandby()void

Resume from a mid-session standby (SPA navigate-away pause). On WebGL the conversation memory is preserved; on native targets it remains a hard reset. Not the way to bootstrap the first session — use startSession() for that.

enterStandby(text?: string)void

Pause the session (e.g. user navigated to another page on the host site). Soft pause on WebGL — memory preserved; hard reset on native. Optional standby text.

Window
setTheme(theme: "dark" | "light")void

Switch between dark and light theme.

getTheme()"dark" | "light"

Get the current theme.

setFullscreen(enabled: boolean)void

Toggle fullscreen mode.

isFullscreen()boolean

Check if widget is fullscreen.

setVolume(volume: number)void

Set avatar speech volume (0 to 1).

getVolume()number

Get the current volume level.

setDebugWindow(visible: boolean)void

Show or hide the debug overlay.

isDebugWindowVisible()boolean

Check if debug overlay is visible.

requestClose()void

Request the widget to close.

Chat
sendSystemMessage(message: string, triggerResponse?: boolean)void

Send a system message. If triggerResponse is true (default), the persona will respond. If false, the message is added to memory only.

getChatHistory(count?: number)ChatMessage[]

Retrieve recent chat messages. Pass count to limit results.

Devices
requestPermission(type: "microphone" | "camera")void

Request browser permission for a device.

isPermissionGranted(type: "microphone" | "camera")boolean

Check if a device permission is granted.

getDevices(type: "microphone" | "camera")string[]

List available devices of the given type.

setDevice(type: string, name: string | null)void

Select a specific device by name, or null for default.

getSelectedDevice(type: string)string | null

Get the currently selected device name.

Environment
setEnvironment(settings: EnvironmentSettings)void

Update the avatar's environment (background, lighting).

getEnvironment()EnvironmentSettings

Get the current environment settings.

Presentation
isPresentationOpen()boolean

Check if the hologram dashboard is currently open.

Event Callbacks

Assign these on window.PersonAIzer before loading widget.js to receive events.

onAppStateChanged: (state: AppState) => void

Fires when the widget lifecycle state changes.

onQueueStateChanged: (position: number, estimatedWaitSeconds: number | null) => void

Fires when queue position updates.

onConsentStarted: () => void

Fires when the consent animation begins.

onLiveEntered: ({ consentAccepted: boolean }) => void

Fires when the persona goes live.

onChatUpdated: (msg: ChatMessage) => void

Fires when a new chat message arrives.

onPermissionChanged: (device: string, granted: boolean) => void

Fires when a device permission changes.

onDeviceSelected: (device: string, name: string) => void

Fires when a device is selected.

onPresentationChanged: (viewId: string | null) => void

Fires when the hologram dashboard opens or closes.

Types

AppState

Widget lifecycle states

"loading"WebGL assets downloading, or engine ready and waiting for startSession()
"queue"Waiting in server queue (after startSession)
"initializing"Unity scene and persona initializing
"standby"Mid-session pause — call exitStandby() to resume in-context
"consent"Showing consent prompt
"live"Fully active — persona is conversational
"error"Fatal error occurred
ChatMessage

Chat message object

MessageTypenumber — ChatMessageType enum
Authorstring — sender name
Messagestring — message content
TimestampMsnumber — unix timestamp in ms
ChatMessageType

Message author types

0 = EndUserFrom the end user (typed or voice)
1 = SystemUserProgrammatic system message
2 = PersonaAI persona response
3 = SystemSystem event (interrupted, error, etc.)
EnvironmentSettings

Avatar environment configuration

Typenumber — 0 = solidColor, 1 = image, 2 = room
SolidColorHexstring — e.g. "#000000"
ImageUrlstring | null
GlobalLightIntensitynumber — 0 to 1
EnvironmentLightIntensitynumber — 0 to 1
LightColorHexstring — e.g. "#ffffff"
LightDirection{ X, Y } — -1 to 1