Session management in this fork covers the full lifecycle of a visitor’s identity and conversation inside the widget: how a new contact is created when a visitor first opens the chat, how the session persists as the visitor navigates between pages, and how it is cleanly reset when the conversation ends — either because the visitor clicks “Exit Chat” or because the dashboard resolves the conversation remotely. The central design constraint is that the iframe must never be reloaded during a reset. A full iframe reload causes a white flash visible to the visitor and breaks any host page code that listens for theDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/jAtInn71/chatwoot-costom/llms.txt
Use this file to discover all available pages before exploring further.
exitChat postMessage event. All exit paths in this fork perform a “soft exit” instead.
Contact creation and auth token
When the widget loads and no existing session is found in storage,custom/widget/api/contacts.js creates a new anonymous contact by calling GET /api/v1/widget/contact?website_token=…. The server responds with a widget_auth_token that is saved to localStorage and set as the X-Auth-Token request header for all subsequent API calls.
The WEBSITE_TOKEN used in every API URL is captured once at module load time from the original iframe URL query string. It is intentionally not cleared during exit because it is configuration data (which inbox this widget belongs to), not session data. Clearing it would cause website_token = null errors on every API call after a reset.
App.vue rehydrates the session by calling fetchOldConversations and getAttributes, which resume the existing conversation without showing the pre-chat form again.
Soft exit flow
All three exit triggers — user clicking “Exit Chat”, the dashboard resolving the conversation, and the auto-resolve inactivity timer — converge on the same four-step sequence:Resolve the conversation server-side
toggleStatus is called to set the conversation status to resolved via GET /api/v1/widget/conversations/toggle_status. This step only runs for the user-initiated exit path; auto-resolve and dashboard-initiated closes have already resolved the conversation before the widget detects them.Dispatch contacts/softExitChat
contacts/softExitChat (custom/widget/store/modules/contacts.js:281) resets Vuex contact state to a blank user object, removes the X-Auth-Token, api_access_token, and user_access_token axios headers, and calls clearSessionStorage().Critically, it does not post { event: 'exitChat' } to the parent and does not call window.location.reload(). The iframe stays alive.clearSessionStorage removes session keys from both localStorage and sessionStorage, sweeps any remaining cw_* / cwc* / widget_auth* keys, expires matching cookies, and strips session params from the iframe URL — all while leaving chatwoot_user_data intact so the pre-chat form can be pre-filled on the next session.Navigate the router to home
router.replace({ name: 'home' }) is called immediately after the Vuex reset. The next paint renders the team-availability home view. Because conversationSize is now 0, the home view will route to the pre-chat form when the visitor starts a new conversation.Code touchpoints
| File | What it does |
|---|---|
custom/widget/store/modules/contacts.js:281 — softExitChat | Clears Vuex state, auth headers, and session storage |
custom/widget/components/HeaderActions.vue:91 — endChat | User-initiated exit: calls toggleStatus, then softExitChat, then closeWindow |
custom/widget/views/App.vue:374 — checkAndClearResolvedConversation | Dashboard/auto-resolve path: detects resolved status, calls softExitChat, then closeWindow |
Auto-resolve detection (polling)
App.vue polls the conversation status to detect when the dashboard or an inactivity timer has resolved the conversation externally. The polling logic is intentionally lightweight:
isWidgetOpen— polling only runs while the chat panel is open. No background polling when the visitor is reading the host page.conversationSize > 0— polling only runs when a conversation actually exists, preventing console errors on the empty home view.
checkAndClearResolvedConversation is called immediately every time the widget bubble is opened (on the toggle-open postMessage event), so a conversation that was resolved while the widget was closed is detected on the very next open.
A 404 response from the conversation endpoint is treated the same as a resolved status — the soft exit flow runs in both cases.
Session storage keys
clearSessionStorage removes these keys explicitly, then sweeps any remaining cw_* and cwc* keys:
chatwoot_user_data is intentionally excluded from the sweep. It stores the visitor’s name and email so the pre-chat form can be pre-filled the next time they open the widget, without resuming the previous conversation.