The problem
Selling an AI chatbot is easy. Operating one across hundreds of brands isn't. Customers need a widget that drops into their site, an inbox that unifies email + SMS + social, and per-tenant theming that doesn't require a new build for each customer.
What I built
Frontend UI/UX architecture for the platform's main app + the embeddable widget that ships into customer sites.
The widget is a single tiny JS bundle (~14KB gzip) that opens an iframe into a per-tenant frontend, theme-derived from a tenant settings object. The agent inbox unifies channels via a normalised message shape — same React tree renders an email thread, an SMS conversation, or a social DM with channel-specific affordances on the edges.
Real-time is plain WebSocket with a reconnect strategy keyed off the last-seen message ID so dropped connections don't lose history.
Decisions worth flagging
- One frontend per tenant, not per channel. Channel becomes a property of a message, not a separate UI. Cut maintenance roughly in half versus the previous per-channel React app.
- Theming as data, not as code. A tenant's brand colors / radii / font stack live in a JSON object and feed CSS vars, not a Tailwind config rebuild.
- Optimistic UI for agent replies. Reply appears in the thread before the WebSocket round-trip confirms — undo on failure rather than block on success.