Integrate with an AI Coding Assistant
The recommended application-code integration is the @openstaticfish/chattybox npm package. It lets code configure the public key and API URL, load ChattyBox's maintained floating widget from a persistent browser layout, or use the headless client for a completely custom UI.
The standalone widget.js script is documented last as a no-build fallback for sites that cannot install npm packages.
Before You Start
Complete the chatbot setup before asking an assistant to edit your application:
- Verify representative answers and citations in Test chatbot.
- Under Install → Keys & domains, inspect or create a public browser key and check its origin settings. A key prepared for a website may already be restricted; keys created without restrictions work across origins. Restrictions are optional hardening, not visitor authentication.
- Under Install → Website installation, select a suitable key and copy the snippet. Use its
data-api-urlwhen present; otherwise obtain the correct widget HTTP endpoint from your deployment configuration before integrating. - Decide whether a persistent floating widget fits the application or you need a custom UI with route-scoped placement and teardown.
These are public browser credentials, but you should still avoid committing environment-specific values. Never provide a config deployment token, admin credential, or unrelated environment file.
Recommended: Mount the Maintained UI from npm
This is the default prompt for React, Next.js, Vite, and other package-based browser applications.
Integrate ChattyBox into this application using the @openstaticfish/chattybox npm package.
Public browser configuration:
- API key: [PASTE PUBLIC WIDGET KEY]
- API URL: [PASTE WIDGET API URL]
First inspect the framework, routing model, package manager, environment-variable conventions, and persistent application layout. Tell me which files you plan to change before editing. Ask me if the routes where ChattyBox should appear are unclear.
Requirements:
1. Install @openstaticfish/chattybox with the package manager already used by this repository.
2. Store the public API key and API URL using the framework's browser-exposed environment-variable convention. Add placeholder names to an example environment file, but do not commit real values.
3. Import Chattybox from @openstaticfish/chattybox and create one client with apiKey and baseUrl.
4. Call client.mountWidget() only in browser code after document.body exists, from a persistent application shell. It loads a floating widget under document.body, not inside the component.
5. Keep the loader across allowed SPA navigation. SDK 0.1.4 reference-counts only identical mount options; call remove() on every returned handle for intentional teardown. In current-source hosted widget.js v16, the final handle signals teardown of owned UI/styles and cancels pending initialization, retries, and in-flight chat; window.ChattyBox.destroy() is the hosted equivalent. Check route transitions and consent changes: do not load before required consent or on sensitive/private routes, and tear down on exclusion or revocation. Verify the deployed loader supports teardown; hiding the UI or removing only the script tag is not sufficient. Cleanup cannot undo a request the server already processed.
6. Do not inject widget.js manually, create a backend proxy, or introduce a second loader. mountWidget rejects changed key, API URL, script URL, locale, or debug options until every existing matching handle is removed; it never silently keeps old options.
7. Preserve existing navigation, rendering boundaries, localization, analytics, consent, and styling. The SDK locale option follows the project's script-override policy; SDK 0.1.4 has no reactive locale-update API or ready promise. Current-source hosted widget.js v16 can refresh product-owned labels when the resolved locale changes; verify the deployed loader before relying on this separately versioned behavior. Current-source hosted v16 schedules at most 10 chat attempts within a 30-second retry window, not a hard timeout for an in-flight request; headless sendMessage() does not retry automatically. SDK 0.1.4 validates baseUrl and wraps unreadable response bodies.
8. Make the smallest focused change and do not deploy it.
9. Run the repository's build, lint, type-check, and relevant tests.
10. Report changed files, environment variables I must set, where the UI mounts, and how to test it on the deployed site.The following is an illustrative browser lifecycle callback, not a top-level server-rendering call. Invoke it only after document.body exists and retain its handle for intentional teardown:
import { Chattybox } from '@openstaticfish/chattybox';
const client = new Chattybox({
apiKey: PUBLIC_CHATTYBOX_API_KEY,
baseUrl: PUBLIC_CHATTYBOX_API_URL,
});
function mountInBrowser() {
return client.mountWidget();
}
// Keep the returned handle for allowed navigation and intentional teardown.
Build a Custom Interface
Choose this when your application should own the message list, input, loading states, errors, citations, and placement instead of mounting the maintained interface.
Build a custom chatbot interface using the @openstaticfish/chattybox npm package and its headless client.
Public browser configuration:
- API key: [PASTE PUBLIC WIDGET KEY]
- API URL: [PASTE WIDGET API URL]
First inspect the application's framework, component system, state patterns, styling, accessibility conventions, and test setup. Propose the component boundaries and files before editing.
Requirements:
1. Install @openstaticfish/chattybox with the repository's existing package manager.
2. Configure one Chattybox client with apiKey and baseUrl using browser-exposed environment variables; do not commit real values.
3. Use sendMessage() and retain conversationId in visitor-scoped state to group messages; reset it on user or session changes. Never share it between unrelated visitors. The model receives up to 12 recent saved messages, each clipped to 2,000 characters, not the full transcript or permanent memory. A public key, origin restrictions, and conversation IDs do not authenticate visitors or protect private conversations. Avoid sensitive information: messages may be saved and visible to project owners; clearing local state does not delete server records.
4. Render answers safely as text or sanitized Markdown and render HTTP(S) sources as accessible links, preserving their order. Never insert untrusted raw HTML or unsafe link schemes.
5. Implement pending, empty, error, and retry states. Fallback answers can have empty sources; there is no general wasAnswered flag. When the backend supplies providerError, safely narrow it as an optional field and show a generic provider failure rather than a normal answer; do not blindly retry a completed keyed response. Published SDK 0.1.4 may not type current-source response fields, so tolerate their absence. Handle both ChattyboxError and unwrapped network errors; code is optional.
6. Reject blank or over-2,000-character trimmed messages, prevent duplicate submissions, and keep keyboard and screen-reader behavior usable. Headless sendMessage() does not retry automatically: use one unique idempotencyKey per logical message and reuse the exact input for retries; do not blindly retry every 409. SDK 0.1.4 only retries getWidgetConfig() once after HTTP 400; current-source hosted v16 separately retries startup GETs.
7. Mount the interface only in the routes or layout I specify.
8. Follow existing components and styles instead of adding a new design system.
9. Do not load widget.js or call mountWidget().
10. Run build, lint, type-check, and relevant tests, then report changed files and a verification plan.Framework Notes
Give the assistant one additional sentence when needed:
- Next.js App Router: “Use a small Client Component in a persistent layout, and call
mountWidget()from a browser-only effect, not during rendering.” - React SPA: “Mount from the persistent app shell. If the component owns the final SDK-0.1.4 handle, return
remove()for intentional teardown; otherwise retain the shared loader across route changes.” - Docusaurus: “Initialize from
src/theme/Rootin browser code and keep the loader across allowed docs navigation. Verify the deployed hosted-loader version and locale behavior before relying on client-side language updates; dashboard configuration changes still require reinitialization.” - Vue, Nuxt, Svelte, or another framework: “Use the client-only mount lifecycle in a persistent layout; choose a headless UI if matching teardown is required.”
Review an Existing SDK Integration
Review this ChattyBox integration without deploying or changing unrelated code.
Check that:
1. @openstaticfish/chattybox is installed and imported instead of duplicating its behavior.
2. One Chattybox client receives the intended public API key and API URL.
3. Browser environment variables follow this framework's public-variable naming rules without exposing private credentials.
4. A hosted widget uses a persistent shell and uses remove() only for intentional UI teardown, route exclusions after SPA navigation, or consent revocation. A custom interface has real component cleanup.
5. Client-side navigation and development remounts do not create duplicate instances.
6. Existing rendering boundaries, localization, analytics, consent, accessibility, and layout remain intact. Origin restrictions are optional, not visitor authentication; restricted keys need an allowed request origin, and Node fetch does not automatically supply browser headers. Confirm private routes and consent revocation actively tear down an initialized widget rather than merely hiding it.
7. The implementation has appropriate tests and no unrelated refactor.
Return findings by severity with file paths and line references. Propose only the smallest safe fixes and give me exact verification commands.No npm or Build Step?
Use the widget.js installation guide only when the site cannot use the npm package—for example, plain HTML, a CMS custom-code field, or Google Tag Manager.
Install the hosted ChattyBox widget on this site using the exact script generated by my ChattyBox Website installation view:
[PASTE COMPLETE WIDGET SCRIPT]
Inspect the site first and identify the safest public-page insertion point. Load the unchanged script exactly once only when required consent is present; exclude private/admin/checkout routes. On SPA route changes or consent revocation, intentionally tear down any initialized widget before entering an excluded state, and reinitialize only when allowed. Verify deployed loader teardown support; hiding the UI or removing the script tag alone is insufficient, and teardown cannot undo processed requests. Preserve CSP behavior, do not expose private credentials, do not deploy the change, and report the changed location plus a browser test plan.Test the Result
- Review the diff and confirm no real credentials were committed.
- Run the project's normal build, lint, type-check, and tests.
- Deploy through the normal review process.
- Verify the intended routes in a private browser window, including client-side navigation.
- Ask a supported question, follow a citation, and test the fallback behavior.
- Check mobile layout, keyboard use, and the browser console.
Continue with the SDK reference and launch checklist.