Skip to main content
Deploy the browser artifact and API as a compatible pair. This guide reflects the reviewed 1.2.13 workspace plus local work on October 20, 2026; it does not establish what a hosted storefront or published image currently runs.

Ship one complete browser artifact

npm run build produces the entry bundle and stylesheet, content-hashed copies, lazy chunks, licenses, vendored React files, embed.js and asset-manifest.json. Keep the chunks next to the bundle and preserve vendor/. The built loader contains that build’s filenames and SRI values; data-rw-asset-base changes their base URL, not which build they reference. Upload immutable assets before switching the loader/manifest, and retain previous hashed assets for rollback. Cross-origin SRI requires CORS-readable asset responses. Byte-rewriting CDN optimizations break integrity checks; normal gzip/brotli encoding is compatible. The static Dockerfile/Nginx image serves browser assets; Dockerfile.server packages the API. Reset the source loader with npm run embed:reset after a local build, while retaining the complete built artifact for publication.

Configure the API

For normal production startup set the selected provider key, ALLOWED_ORIGINS, and STATESET_WIDGET_AUTH_SECRET. AI_PROVIDER accepts openai, anthropic or gemini. An explicit STATESET_WIDGET_AUTH_REQUIRED=false permits a tokenless compatibility deployment; it does not establish verified conversation ownership for the native inbox or analytics. Use verified tokens and enforce them after qualifying existing storefronts. Without Redis, stores are process-local and disappear on restart. Run one replica for that mode. Production multi-replica operation needs shared Redis plus a persistence policy suitable for the conversations you retain. Use GET /api/health for liveness and /api/ready for readiness. Readiness stays 503 until thread, rate-limit, response-outbox and execution stores initialize. Thread reads are rate-limited too: allow for visitor polling when sizing budgets rather than bypassing access checks or the limiter.

Response reporting

When Hasura response reporting is configured, the server queues stable response IDs and retries background delivery. By default enqueue failure logs/counts the loss and allows chat to continue. RESPONSE_OUTBOX_STRICT=true makes enqueue success a reply precondition and requires a durable Redis outbox in production when reporting is configured. Queue failure can then return 503 or an SSE error without [DONE]. Monitor pending records, enqueue failures and confirmed deliveries separately from HTTP success. The strict queue acknowledgement is not a transaction spanning provider actions, commerce mutations, helpdesk writes and reporting.

Enable sessions and native support in stages

Prepare the admin database and credentials, then bind the public session issuer to exact website origins, org/agent and optional site. Store secrets in the deployment’s secret manager. Match WIDGET_SESSION_ALLOWED_ORIGINS with CORS ALLOWED_ORIGINS and keep session TTL between 60 and 900 seconds. The repository’s scripts/prepare-live-chat-rollout.js produces a strategic merge patch for known deployment bindings and an immutable GHCR digest. It does not apply it. Review the selected deployment’s origins and bindings before using the generated patch. Do not infer legacy conversation ownership from visitor metadata. Inside each candidate API pod, with its runtime environment and operator credential:
Use the matching pilot or enforced phase later. Preflight checks liveness/readiness, authenticated inbox access, a ready Redis thread store, issuer bindings and Hasura schema. Exit 0 means ready, 1 failed and 2 incomplete; omitting --runtime leaves checks pending. An unauthenticated 401 by itself does not prove readiness. Qualify a signed visitor turn and operator reply across different replicas. Check wrong-tenant denial, notes absent from visitor/model transcripts, stable-ID duplicate protection, and token renewal without a remount or lost draft. An old replica can still generate AI replies during takeover, so every replica needs the native handler before enabling support.

Release evidence

The current CI/release workflow records asset SHA-256 values in release-evidence.json, serves that artifact for browser checks, verifies both images against it, and uses the same bytes for tag publication. Source mismatches, uncommitted source and stale extra chunks fail the artifact gate. WIDGET_ASSET_DIR selects an isolated artifact directory for checks. Tag publication also requires a configured WIDGET_CANARY_URL. JSON and real SSE replay must both pass; a JSON fallback does not pass the streaming gate. Canary reports record attempt/check counts without transcript text or capabilities and reference the verified asset-evidence digest. These gates establish the cases exercised. Physical iPhone use, screen-reader review and real-provider answer quality still need separate evidence. If a rollout fails qualification, restore the prior image/loader and feature flags, preserving additive tables and credentials. Release controlled operator claims before disabling live chat. See native live chat for the operator flow.
Last modified on November 13, 2026