Customer Support
Add Crisp live chat with lazy loading and logged-in user identity sync.
ShipNext uses Crisp for live support chat. The implementation is a lightweight Client Component at src/modules/messages/components/crisp-chat.tsx.
It is independent from:
- Transactional email in
src/modules/email/ - Operational notifications in
src/modules/notify/ - Static contact pages such as
/contact
Architecture
| File | Responsibility |
|---|---|
src/modules/messages/components/crisp-chat.tsx | Configures Crisp, lazy-loads the SDK, syncs logged-in user email/name |
| Marketing layout | Mounts <CrispChat /> for public pages |
The component returns null; the chat bubble is injected by the Crisp SDK.
Enable Crisp
Get the Website ID
Create a Crisp workspace, then open Settings -> Setup and copy the Website ID.
Configure the environment variable
NEXT_PUBLIC_CRISP_WEBSITE_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxIf the variable is empty, the SDK is not loaded and no chat bubble appears.
Verify locally
Open a marketing page such as / or /pricing. After about 5 seconds, the chat bubble should appear. If you are logged in, Crisp should receive the user's email and name.
Runtime behavior
Lazy loading
The component registers the Website ID without immediately downloading the SDK:
Crisp.configure(websiteId, { autoload: false });
const timer = setTimeout(() => {
Crisp.load();
}, 5000);Adjust the 5000 millisecond delay in crisp-chat.tsx if needed.
User identity sync
When session.user.email exists:
Crisp.user.setEmail(user.email)Crisp.user.setNickname(user.name)if a name exists
Crisp queues these calls even if the SDK has not loaded yet.
Display scope
The default setup mounts chat in marketing pages only. Dashboard and protected pages do not show Crisp unless you add <CrispChat /> to their layout.
Customization
- Public pages only: keep the current marketing layout placement.
- Entire app: move
<CrispChat />higher in the layout tree. - Remove chat: delete the component from the layout and clear
NEXT_PUBLIC_CRISP_WEBSITE_ID. - Sync more fields: add calls such as
Crisp.user.setAvatar(user.image)when available.
Privacy
Disclose Crisp or similar third-party scripts in your privacy and cookie policies. If you need cookie consent, delay Crisp.load() until the user accepts the relevant category.
Troubleshooting
| Symptom | Possible cause | Fix |
|---|---|---|
| No chat bubble | Missing or wrong Website ID | Check .env.local, restart dev server |
| Works locally, not in production | Missing production env var | Add it to the deployment platform and redeploy |
| Bubble appears after a delay | Intentional 5 second lazy load | Expected, or reduce the delay |
| User email missing in Crisp | User is not logged in or session lacks email | Only logged-in users sync automatically |
| No Dashboard chat | Component not mounted in protected layout | Add <CrispChat /> there if desired |