Architecture
The Open Chat Widget deployment consists of three main components:- Convex Project - Serverless backend for conversations and messages storage
- Backend API - Node.js/Express server handling OpenAI streaming and widget requests
- Dashboard (optional) - Next.js admin interface for viewing conversations
- 1 Convex project
- 1 backend deployment
- 1 dashboard deployment (optional)
- Any number of websites/apps embedding the widget or calling the headless API
Deployment Targets
Convex
- Deploy to Convex Cloud using
npx convex deploy - See Convex Deployment for details
Backend
Supported platforms:- Render
- Railway
- Fly.io
- Any Node.js host
- Docker (self-hosted)
Dashboard
Recommended platform:- Vercel (optimized for Next.js)
- Any Node.js host
- Docker (self-hosted)
Recommended Setup
Step 1: Deploy Convex
CONVEX_URL (e.g., https://your-deployment.convex.cloud)
Step 2: Deploy Backend
Deploy to your chosen platform with required environment variables:CONVEX_URL- Your production Convex URLOPENAI_API_KEY- Your OpenAI API keyWIDGET_API_KEY- Strong random secret for widget authenticationCORS_ORIGIN- Comma-separated list of allowed origins
Step 3: Deploy Dashboard (Optional)
Deploy to Vercel or your chosen platform with:CONVEX_URL- Your production Convex URLNEXT_PUBLIC_BACKEND_URL- Your backend URLDASHBOARD_PASSWORD- Strong password for admin access
Step 4: Embed Widget
Add the widget script to your website:Production Smoke Tests
Verify your deployment:GET https://<backend>/healthreturns{"status":"ok"}GET https://<backend>/widget/chat-widget.jsreturns JavaScriptPOST https://<backend>/v1/chatreturns JSON replyPOST https://<backend>/v1/chat/streamstreams NDJSONGET https://<backend>/v1/openapi.jsonreturns OpenAPI document- Dashboard login works at
/login
Security Considerations
- Rotate all API keys and passwords regularly
- Keep
OPENAI_API_KEYserver-side only - Restrict
CORS_ORIGINto trusted domains (never use*in production) - Serve all services over HTTPS
- The backend includes rate limiting by default
- API key/password checks use timing-safe comparison