FluxyChat

Reference

Embeddable chat widget (P12-A)

One-line install for a support chat bubble on any website, powered by public guest sessions (P10-SB6) and optional custom domains (P12-G).

Quick start

  1. Open dashboard Embed widget (/embed).
  2. Set a public room as defaultRoomId.
  3. Add allowed parent origins (e.g. https://www.acme.com).
  4. Copy the generated <script> snippet before </body>.

Live demo

Open the hosted console Embed widget at /embed to configure origins, theme, and copy the install snippet. For a minimal static test page, paste the snippet into any HTML file served from an allowed origin:

<!DOCTYPE html>
<html lang="en">
  <head><meta charset="utf-8" /><title>Embed demo</title></head>
  <body>
    <h1>Support site</h1>
    <!-- paste snippet from dashboard -->
  </body>
</html>

Script attributes (optional overrides):

AttributePurpose
data-fluxy-api-urlWorker / custom domain origin
data-room-idDefault public room
data-primary-colorLauncher + header color
data-positionbottom-right or bottom-left
data-launcher-titleAccessibility label
data-z-indexStacking above site chrome
<script
  src="https://chat.acme.com/embed.js"
  data-fluxy-api-url="https://chat.acme.com"
  data-room-id="room_support"
  data-z-index="2147483000"
  async
></script>

Architecture

sequenceDiagram
  participant Site as Customer website
  participant Embed as embed.js (bubble)
  participant Frame as /embed/frame iframe
  participant Worker
  participant Room as Room DO

  Site->>Embed: load script (parent origin)
  Embed->>Frame: iframe ?parentOrigin=&roomId=
  Frame->>Worker: POST /public/rooms/\:id/guest-session
  Note over Worker: validate embedParentOrigin allowlist
  Worker-->>Frame: guest JWT
  Frame->>Room: WebSocket /ws/room/\:id

Security

ControlPurpose
Origin allowlistallowedOrigins on embed config + active custom-domain origins
embedParentOriginIframe passes parent page origin; guest-session rejects unknown sites
Z-index sandboxLauncher uses configurable high z-index without touching page CSS
iframe sandboxallow-scripts allow-same-origin allow-forms allow-popups
Global kill switchEMBED_WIDGET_ENABLED=false disables /embed.js and public config

API

MethodPathAuthPurpose
GET/embed.jsnoneVanilla IIFE loader
GET/embed/framenoneChat shell (iframe target)
GET/public/embed-confignonePublic widget metadata
GET/admin/embed-configJWT adminRead config + snippet
PATCH/admin/embed-configJWT adminEnable / theme / origins

Environment

VariableDefaultNotes
EMBED_WIDGET_ENABLEDenabledSet false to disable widget globally
PUBLIC_GUEST_ALLOWED_ORIGINSStill applies to guest-session
PUBLIC_GUEST_READ_ONLYread-only guestsWhen false, embed visitors can send messages

Custom domains

Serve embed.js from https://chat.yourcompany.com (P12-G) so API, iframe, and WebSocket share the same origin. Parent marketing site origins still go in the embed allowlist.

Migration

Apply D1 migration 0058_embed_widget.sql (project_embed_configs).

On this page