Skip to main content

Website Widget

The Website Widget is Qefro’s embeddable Customer AI chat. It loads from https://cdn.qefro.com/widget.js (or your configured CDN), authenticates with a publishable widget token, and streams replies over WebSocket (/ws/chat) with HTTP fallback (POST /api/v1/widget/chat).

Introduction​

Configure appearance and copy the embed snippet from Admin Console → Widget. Select a workspace so the live preview and embed data-workspace-id stay aligned.

Supported surfaces in the widget implementation:

  • Text chat with streaming
  • Optional lead capture
  • Message feedback
  • Human handoff / ticket triggers
  • Voice STT/TTS via /api/v1/widget/stt and /api/v1/widget/tts
  • setContext() for page/product context
  • identify() for end-user identity (Business Tools)

Why it exists​

Customer AI must ship on your website without hosting RAG infra. The widget is the public channel; knowledge and tools stay on api.qefro.com under your tenant.

Concepts​

ConceptDetail
Widget tokenPublishable embed key; rotatable in Admin Console
data-endpointUsually https://api.qefro.com
data-workspace-idBinds chat to a workspace knowledge/tools set
Visitor sessionContinuity cookie/header separate from identify()
End-user identityHost-owned JWT/session via identify()

Architecture​

Workflow​

Deploy the widget

  1. Pick workspace — Admin Console → Widget → select workspace.
  2. Copy embed — Paste script tag before </body>.
  3. Optional identify — Call widget.identify() after your app login.
  4. Test — Anonymous + authenticated flows; rotate token if leaked.

Code examples​

<script
src="https://cdn.qefro.com/widget.js"
data-token="YOUR_WIDGET_TOKEN"
data-endpoint="https://api.qefro.com"
data-theme="auto"
data-position="bottom-right"
data-primary-color="#7c3aed"
data-welcome-message="Hi! How can we help?"
data-workspace-id="YOUR_WORKSPACE_ID">
</script>

Identity transport (real widget behavior):

  • JWT mode → HTTP header X-End-User-Token, WebSocket field endUserToken
  • Session mode → X-End-User-Session / endUserSession
  • Profile fields (id, email, name, authMode) go in the request body — tokens are never placed in the JSON body

Best practices​

  • Always set data-workspace-id for production embeds
  • Call identify() only after your own auth succeeds
  • Rotate the widget token if it leaks; update every embed
  • Use clearIdentity() on logout

Security notes​

FAQ​

What endpoints does the widget call?
Primary: WebSocket /ws/chat. Fallback: POST /api/v1/widget/chat. Also settings, leads, feedback, handoff, STT/TTS, and identity/clear under /api/v1/widget/*.
Is identify() required?
No for anonymous FAQ bots. Yes when Business Tools must run as a specific end user.