Embed Widget
J.O.S.I.E ships as a lightweight widget.js bundle loaded from your J.O.S.I.E app URL.
Prerequisites
- Active paid subscription (Basic or above)
- API key created under Dashboard → API Keys
- Allowed origin matching your site's URL scheme + host
Without allowed origins, the embed page blocks copying the snippet — configure domains first.
Standard floating widget
Paste before </body>:
<!-- J.O.S.I.E Chat Widget -->
<script
src="https://your-josie-domain.com/widget.js"
data-josie-key="wk_live_YOUR_API_KEY"
data-app-name="Your Business"
data-placeholder="Ask me anything..."
data-track="false"
async
></script>
This renders a floating launcher button; clicking opens the chat panel.
If the subscription is inactive or expired, the script does not mount the bubble or panel — no host-side billing check is required.
Inline embed (fixed container)
For a dedicated support page or app section:
<div id="josie-chat" style="height: 520px;"></div>
<script
src="https://your-josie-domain.com/widget.js"
data-josie-key="wk_live_YOUR_API_KEY"
data-app-name="Your Business"
data-target="#josie-chat"
data-track="false"
async
></script>
Data attributes
| Attribute | Required | Default | Description |
|---|---|---|---|
data-josie-key | Yes | — | Your wk_live_... widget API key |
data-app-name | No | From config | Display name in chat header |
data-placeholder | No | "Ask me anything..." | Input placeholder text |
data-target | No | — | CSS selector for inline mount (omit for floating bubble) |
data-track | No | false | Enable behavior tracking — set to "true" to collect page views, clicks, and scroll depth |
data-theme | No | auto | Force "dark" or "light" mode |
data-position | No | right | Floating bubble position: "left" or "right" |
data-require-consent | No | false | When "true", tracking waits until window.josieConsentGranted() is called |
Behavior tracking
When data-track="true" is set and behavior tracking is enabled in your dashboard (Dashboard → Configure → Behavior Tracking), the widget collects anonymous visitor activity:
- Page views — every page the visitor loads
- Scroll depth — 25%, 50%, 75%, 100% milestones
- Clicks — buttons and links (text or
data-josie-labelattribute) - Time on page — heartbeat every 30 seconds
- Chat interactions — widget open/close, messages sent/received
Both conditions must be true:
data-track="true"in the script tag and the setting enabled in the dashboard. If either is off, no events are collected.
GDPR / consent gate
If you need explicit user consent before tracking:
<script
src="https://your-josie-domain.com/widget.js"
data-josie-key="wk_live_YOUR_API_KEY"
data-track="true"
data-require-consent="true"
async
></script>
Then call this after the user accepts your cookie banner:
window.josieConsentGranted();
Viewing visitor data
Once events are collected, visit Dashboard → Visitors to see anonymized visitor timelines.
How authentication works
- Browser loads
widget.jsfrom your allowed origin - Widget sends chat requests with
Authorization: Bearer wk_live_... - Server validates key hash, tenant status, message quota, and origin
- Responses stream back to the widget UI
Keys are hashed at rest — only the prefix is shown in the dashboard after creation.
React / SPA sites
Install the package:
npm install josie-widget
Add the component (must be a Client Component in Next.js App Router):
"use client";
import { JosieChat } from "josie-widget";
export default function ChatWidget() {
return (
<div style={{ height: "600px" }}>
<JosieChat
apiKey="wk_live_YOUR_API_KEY"
apiUrl="https://your-josie-domain.com"
appName="Your Business"
placeholder="Ask me anything..."
enableTracking={true}
/>
</div>
);
}
JosieChat is the chat panel only. It returns null when access is inactive or expired. If you add your own floating open/close button, hide that launcher with onAvailabilityChange (the widget resolves access via J.O.S.I.E — you do not call Billing yourself):
"use client";
import { useState } from "react";
import { JosieChat } from "josie-widget";
export default function SupportChat() {
const [open, setOpen] = useState(false);
const [available, setAvailable] = useState(true);
if (!available) return null;
return (
<>
{open && (
<JosieChat
apiKey="wk_live_YOUR_API_KEY"
apiUrl="https://your-josie-domain.com"
appName="Your Business"
onAvailabilityChange={(enabled) => {
setAvailable(enabled);
if (!enabled) setOpen(false);
}}
/>
)}
<button type="button" onClick={() => setOpen((o) => !o)}>
{open ? "Close" : "Chat"}
</button>
</>
);
}
React props
| Prop | Type | Default | Description |
|---|---|---|---|
apiKey | string | Required | Your widget API key |
apiUrl | string | https://josie.ai | Base URL of your JOSIE deployment |
appName | string | From config | Display name in chat header |
placeholder | string | "Ask me anything..." | Input placeholder |
suggestions | string[] | — | Quick-reply chips on the welcome screen |
enableTracking | boolean | false | Enable behavior tracking |
requireConsent | boolean | false | Wait for josieConsentGranted() before tracking |
onAvailabilityChange | (enabled: boolean) => void | — | Fired when access is resolved (and on subscription 403). Hide host FABs when enabled is false. |
Copy ready-to-use snippets from Dashboard → Embed (Script / React / Mobile tabs) — snippets automatically include the correct data-track value based on your current dashboard settings.
Mobile WebView
Use the inline embed inside a WebView with a fixed height. Ensure the WebView origin is in allowed origins (custom URL schemes may need Enterprise support).
For a custom mobile chat UI (REST), call GET /api/widget-settings first. If chatEnabled is false, do not show the chat screen. Treat chat 403 errors that mention subscription / billing / access period the same way.
Troubleshooting embed
| Symptom | Fix |
|---|---|
| Widget doesn't appear | Check browser console; verify origin allowlist; renew in Billing if access expired |
| Chat panel gone but custom FAB remains | Wire onAvailabilityChange on JosieChat (see React section above) |
| 401 / invalid key | Regenerate key; update data-josie-key |
| 403 origin | Add exact origin including https:// |
| Quota exceeded | Upgrade plan or wait for monthly reset |
| Visitors page empty | Ensure data-track="true" is in your script tag and behavior tracking is enabled in Dashboard → Configure |
Content Security Policy (CSP)
Allow:
script-src— your J.O.S.I.E hostconnect-src— your J.O.S.I.E host (API calls)img-src— your J.O.S.I.E host (avatar)
Example:
script-src 'self' https://your-josie-domain.com;
connect-src 'self' https://your-josie-domain.com;