KlicForge Docs
Build

Widget SDK

Embed and control the KlicForge chat widget from JavaScript — installation, configuration, methods and events.

The widget SDK embeds the KlicForge chat widget in a web page and gives you a JavaScript API to control it.

The widget renders inside an isolated container, so its styles cannot leak into your page and your page's styles cannot break it.

Installation

Add this before the closing </body> tag:

<script src="https://unpkg.com/@bymos/[email protected]/agentkit-widget.iife.js"></script>
<script>
  window.AgentKit.init({
    agentId: 'your-agent-id',
    tenantId: 'your-tenant-id',
    apiBaseUrl: 'https://api.klicforge.ai',
  });
</script>

This registers window.AgentKit synchronously.

Find your agent ID and workspace ID in the dashboard, and get a ready-made copy-paste snippet on the agent's Sandbox tab, or from an agent's Channels → Widget settings.

The widget only loads on domains listed in the agent's allowed origins. If you see an access-restricted message, add the site's origin under the agent's Channels → Widget settings.

Mounting

init() creates a floating widget with a launcher button. To embed the chat inside an element of your own layout instead, use mount():

window.AgentKit.mount(document.getElementById('support-chat'), {
  agentId: 'your-agent-id',
  tenantId: 'your-tenant-id',
  apiBaseUrl: 'https://api.klicforge.ai',
});

Configuration

init() and mount() accept these fields:

FieldTypeNotes
agentIdstringRequired.
apiBaseUrlstringRequired.
tenantIdstringTenant/organisation identifier. Required for conversation tracking and widget validation.
userobjectIdentity of the end-user — see Identifying your users.
sessionIdstringResume a specific session instead of the one persisted in localStorage.
mode'floating' | 'inline'Default 'floating'. Use 'inline' with mount() to embed in an element of your layout.
titlestringDefault 'AI Assistant'. Overrides the agent's display name in the header.
subtitlestringShort text shown below the agent name in the widget header.
descriptionstringUsed in the widget empty state. Defaults from the server; can be overridden here.
avatarUrlstringURL of the avatar image shown in the header and launcher.
themeobjectmode ('light' | 'dark' | 'system'), accentColor, fontFamily, borderRadius.
metadataRecord<string, unknown>Arbitrary metadata attached to the session.
streamingbooleanDefault true. Set false to receive whole replies instead of token streams.
previewbooleanDashboard sandbox only. Sends the session cookie so a signed-in tenant member can chat with a draft/inactive agent. Leave false for third-party embeds.
skipServerConfigFetchbooleanDashboard sandbox only. Skips the SDK's own config fetch when the host already supplies display fields inline.
configChannel'draft' | 'published'Dashboard sandbox only. 'draft' requires a session cookie for the owning tenant and is inert for third-party embeds.

Controlling the widget

Both init() and mount() return an instance:

const widget = window.AgentKit.init({ ... });

widget.open();
widget.close();
widget.toggle();
widget.sendMessage('Hello');
widget.reset();          // start a fresh conversation
widget.getState();
widget.destroy();

window.AgentKit.destroy(id) removes a widget by ID, and calling it with no argument removes all of them.

Events

widget.on('message:received', (event) => {
  console.log(event);
});

widget.off('message:received', handler);
EventFires when
readyThe widget has initialised
open / closeThe widget is opened or closed
conversation:startedA new conversation begins
message:sentThe user sends a message
message:receivedThe agent's reply arrives
message:errorA message fails
stream:start / stream:delta / stream:endStreaming reply lifecycle
control_mode_changedA human takes over or hands back
resetThe conversation is reset
destroyThe widget is torn down

Identifying your users

If you already know who the visitor is, pass an external identifier so their conversations link to the same contact across sessions and devices.

window.AgentKit.init({
  agentId: 'your-agent-id',
  tenantId: 'your-tenant-id',
  apiBaseUrl: 'https://api.klicforge.ai',
  user: {
    externalId: 'user_123', // your own DB user ID, UUID, etc.
    authId: 'auth0|abc123', // ID from your auth system — highest-priority lookup key
    name: 'Jane Doe',
    email: '[email protected]',
  },
});

All user fields are optional — omit user entirely for anonymous sessions.

Do not pass personal data you would not want in a browser. The identifier should be an opaque ID from your own system, not an email address.

Appearance

Greeting, branding, colours, whether file upload and voice notes are enabled, and links to your privacy policy and terms are configured on the agent's Widget tab, so non-developers can change them without a deployment. title, avatarUrl, and theme in the init config override those defaults for a specific embed when set — see Configuration.

Sessions

A conversation persists across page loads in the browser, so a visitor who navigates around your site keeps their conversation. reset() starts a fresh one. Sessions expire after a period of inactivity set on the agent.

From 0.8 the SDK also establishes an abuse-protection session when the visitor opens the chat panel. It needs no configuration, adds nothing to a page whose chat is never opened, and a failure to establish one never blocks a message.

Troubleshooting

SymptomLikely cause
window.AgentKit is undefinedThe script tag runs after your init code, or failed to load
Access-restricted messageThe origin is not in the agent's allowed origins
Widget opens but never repliesThe agent's status is draft or inactive
Widget is clipped or invisibleA parent element has overflow: hidden or a low stacking context
Uploads rejectedThe file type or size is not supported
Was this page helpful?

On this page