Full chat is the default the widget mounts when mode is chat (or omitted). It's the floating bubble in the corner that opens to a panel with welcome screen, registration form, history, message composer, and AI/agent routing. The component is ChatApp in src/chat-app.tsx.
Pages inside the panel
The panel has its own router (a path string in the chat store, not React Router). The current path determines which page renders inside the panel:
| Path | Page | Component |
|---|---|---|
/ | Welcome | WelcomePage |
/register | Registration form | ChatRegistrationPage |
/chat, /chat-ai, /chat-agent | Message stream | ChatPage |
/help | Help / FAQ | HelpPage |
/setting | Visitor preferences | SettingPage |
The widget routes between these based on auth state and chat config. An unauthenticated visitor trying to reach /chat is redirected to /register. When the chat config is offline and offline.showForm is enabled, /chat falls through to ChatRegistrationPage so the visitor leaves a message.
Default flow
- Visitor lands on a page with the widget mounted. The bubble shows.
- They click the bubble — panel opens to
/. The welcome screen renders the chat config's title, subtitle, and CTAs. - They click "Start chat". Path moves to
/register(or skips straight to/chatif they're already authenticated and have a session). - They enter name + email. The widget calls
restHelper.register(...)against AppEngine, which returns a guest customer record and a chat-scoped token. Both are persisted tolocalStorageunderappmint-chat-session. - The socket opens with
{ orgId, token }on the auth payload. The visitor joins their conversation room and the agent's queue (or is routed to an AI assistant, depending on the config). - Messages flow in real time. Typing indicators, presence, and status updates flow through the same socket.
Navigation tracking
While the panel is open, the widget tracks URL changes in the host app — popstate, pushState, and replaceState are all intercepted. Each change calls updateContext(newUrl, lastUrl) over the socket so the agent or AI can see what page the visitor is on.
This is automatic. The agent UI in AppMint shows the current page in real time without any extra wiring on your side.
Unread badge
When the panel is closed and a new message arrives from the other side, a red badge appears on the bubble with the unread count. The widget filters messages for entries where from !== myEmail and the status is missing or pending or new. Once the panel is opened the badge clears as messages get marked read.
Broadcast overlay
If an agent starts a screen or camera broadcast for this visitor's room, the widget shows a floating overlay on top of (or alongside) the chat panel. The overlay component (BroadcastOverlay in src/components/chat/broadcast-video.tsx) listens on a separate anonymous socket so it works even when the chat isn't open.
Engage notice
Agents can send a proactive "engage" notice to a visitor via the AppMint admin console. The widget renders it as a floating toast (EngageNotice in src/components/chat/engage-notice.tsx) regardless of whether the panel is open. Clicking the toast opens the panel and routes to /chat.
The engage handler dedupes against seenEngageIds so visitors with both an authenticated socket and the broadcast-only socket don't see the same toast twice.
Offline behaviour
When the chat config has status: 'offline' or the current time falls outside availability hours:
- The widget evaluates with
isWithinOfficeHours(...)fromsrc/utils/availability.tsand stamps_outsideHours: trueon the chat config. - If
offline.showFormis true, the/chatroute falls through toChatRegistrationPageso the visitor leaves a message rather than waiting in queue. - If
offline.showFormis false, the panel hides entirely when the bubble is closed — open click does nothing.
The visitor's submitted offline form is stored as a chat record with no socket session, ready for an agent to pick up later.
Known visitors
If the host app already has an authenticated user, pass user and token as props (see Configuration). The widget skips the welcome and registration screens and lands on /chat directly. The session restore code in src/chat-app.tsx handles this — if a chat session id is also stored in localStorage, it goes straight to /chat; otherwise it lands on / so the visitor can choose to start a new conversation.
When to use Q&A mode instead
Full chat is the right choice when:
- You want a persistent floating bubble.
- The conversation can route to either AI or a human agent.
- You need the welcome screen, broadcast overlay, or engage notices.
Switch to Q&A mode when you want an inline component on the page (no floating bubble), AI-only routing, and a single email gate before the conversation starts.