ShipNext

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

FileResponsibility
src/modules/messages/components/crisp-chat.tsxConfigures Crisp, lazy-loads the SDK, syncs logged-in user email/name
Marketing layoutMounts <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-xxxxxxxxxxxx

If 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

SymptomPossible causeFix
No chat bubbleMissing or wrong Website IDCheck .env.local, restart dev server
Works locally, not in productionMissing production env varAdd it to the deployment platform and redeploy
Bubble appears after a delayIntentional 5 second lazy loadExpected, or reduce the delay
User email missing in CrispUser is not logged in or session lacks emailOnly logged-in users sync automatically
No Dashboard chatComponent not mounted in protected layoutAdd <CrispChat /> there if desired

On this page