← Back

Embedded chat widget

Jun 2, 2026

Peopled had a need to extract our core functionality (the RAG-powered chat system) to be embeddable in customer sites. This resulted in a need for two new large chunks of work:

  • a UI chat widget in the form of a "FAB", that customers can place in their dashboards for their users
  • an auth token system to authenticate these chat users, and make sure they receive org-specific information
    • this project is discussed more in the auth service post

I owned the implementation of both projects end to end, but here I'll talk strictly on the chat module.

A central need for this feature was to be framework agnostic and as close to drop-in as possible, meaning developers needed to be able to plug this into any web framework of their choice (read: Vue, Angular, React). I decided to use web components as it's supported not by a library, but by every modern browser with reasonable backwards support.

The tech is a simple stack:

  • Web Components, using Lit to keep myself sane. Vanilla web components would have meant that I'd have to manually handle re-renders, and I had no interest in that since Lit is so small as a dependency.
  • CSS variables for thematic styling with our design system, allowing easy customer overrides.
  • Typescript, end to end.
  • Vite for the build tooling: library mode made this project a breeze.
  • marked Markdown parser to show our custom charts and info cards. Out of the box, marked obviously has no idea what a "contact card" is, so I extended it with custom tokenizers that recognize our own markdown patterns and emit custom HTML tags, which then get upgraded into their corresponding Lit components (like a contact card) once they hit the DOM. Since this content is ultimately rendered into a page I don't control, I run everything through DOMPurify to make sure things get sanitized before rendering.
  • State managed as a singleton store, instead of adding something like Redux or Zustand. The state surface here is small, so I decided to keep things lean for the consumer.

The devops:

  • This project is published via release-please based github actions
  • Deployed to an S3 bucket, using a cdn to manage distribution