fix: prevent duplicate Crisp conversations with session continuity tokens#1740
fix: prevent duplicate Crisp conversations with session continuity tokens#1740chip-peanut-bot[bot] wants to merge 6 commits intomainfrom
Conversation
…kens Adds CRISP_TOKEN_ID support using a deterministic SHA-256 hash of the user's ID. This ensures the same user always resumes the same Crisp conversation, even if cookies are cleared or they switch devices. Previously, Crisp relied solely on browser cookies for session identity. When cookies were lost (cleared, incognito, iframe cookie partitioning in Safari/Firefox), a new anonymous session was created — leading to duplicate conversations for the same user. Changes: - New hook: useCrispTokenId — generates stable token from SHA-256(userId) - crisp-proxy/page.tsx — sets CRISP_TOKEN_ID before Crisp script loads - useCrispProxyUrl — passes token as URL param to proxy page - SupportDrawer — wires up the token hook - crisp.ts — clears CRISP_TOKEN_ID on logout/session reset - global.d.ts — adds CRISP_TOKEN_ID and CRISP_WEBSITE_ID to Window type Ref: https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/session-continuity/
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Move token setting from useEffect into inline <Script> tag so it's guaranteed to be set before Crisp's l.js loads - Cache generated tokens in memory to prevent undefined→resolved state change that caused iframe reloads - Use proper Window typing instead of (window as any) casts - Revert first useEffect deps back to [] (CRISP_RUNTIME_CONFIG is static)
|
@coderabbitai review Context: This PR adds Key risks to review:
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 11689 🏁 Script executed: Length of output: 9763 |
Adds session_merge: true to CRISP_RUNTIME_CONFIG. This tells Crisp to automatically merge messages from old cookie-based sessions into the new token-based session when a user first opens chat after deploy. Without this, existing users who still have Crisp cookies would get a fresh empty session. With session_merge, their conversation history carries over seamlessly. Ref: https://docs.crisp.chat/guides/chatbox-sdks/web-sdk/session-continuity/#how-to-merge-messages-from-anonymous-sessions-to-token-sessions
|
@coderabbitai review Latest commit adds Please confirm this is safe and doesn't introduce any issues with the existing Crisp config ( |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 12990 🌐 Web query: 💡 Result: Crisp documents Add this before the Crisp chatbox embed loads: <script type="text/javascript">
window.CRISP_RUNTIME_CONFIG = {
session_merge: true
};
</script>Crisp also notes to avoid defining Sources
✅
|
Support agents can now click through to PostHog person page directly from Crisp sidebar to view session recordings and user events. Uses the same userId that PostHog identifies users with.
|
@coderabbitai review |
Problem
Same user opens Crisp support chat → gets multiple separate conversations. Example: Jacob Koch-Gallup got 2 sessions within 1 hour for the same refund issue.
Root cause: Crisp relies on browser cookies for session identity. When cookies are lost (cleared, incognito, Safari/Firefox iframe cookie partitioning), a new anonymous session is created.
Solution
Implements Crisp's Session Continuity system using
CRISP_TOKEN_ID.Generates a deterministic token from
SHA-256(salt + userId)— same user always gets the same conversation, regardless of cookies or device.Changes
src/hooks/useCrispTokenId.tssrc/hooks/useCrispProxyUrl.tscrisp_token_idas URL param to proxy pagesrc/components/Global/SupportDrawer/index.tsxsrc/app/crisp-proxy/page.tsxCRISP_TOKEN_IDbefore Crisp script loads (critical — must be set before init)src/utils/crisp.tsCRISP_TOKEN_IDon logout/session resetsrc/types/global.d.tsCRISP_TOKEN_IDandCRISP_WEBSITE_IDto Window typeHow it works
useCrispTokenIdcomputesSHA-256('peanut-crisp-session-v1:' + userId)CRISP_TOKEN_IDset on window before Crisp JS loadsNotes
Thread: #duplicate-crisp-convos