Crisp
Crisp combines live chat, email, and other customer-messaging channels.
Use useScriptCrisp() for direct SDK calls, or <ScriptCrisp> for a custom chat launcher.
Nuxt Config Setup
Add this to your nuxt.config.ts to load Crisp globally. Alternatively you can use the useScriptCrisp composable for more control.
export default defineNuxtConfig({
scripts: {
registry: {
crisp: {
id: 'YOUR_WEBSITE_ID',
trigger: 'onNuxtReady',
}
}
}
})This config automatically enables first-party mode (bundle). See below to customise.
useScriptCrisp()
The useScriptCrisp composable lets you have fine-grain control over when and how Crisp is loaded on your site.
const { proxy } = useScriptCrisp()
proxy.$crisp.push(['do', 'chat:open'])Please follow the Registry Scripts guide to learn more about advanced usage.
First-Party Mode: Privacy Focused Proxy
No extra config needed. The script is bundled and served from your domain instead of a third-party CDN, eliminating an extra DNS lookup and improving load times. Learn more.
export default defineNuxtConfig({
scripts: {
// ✅ First-party mode: bundled
registry: {
crisp: {
id: 'YOUR_WEBSITE_ID',
trigger: 'onNuxtReady',
},
},
},
})Example
Using Crisp in a component.
<script setup lang="ts">
const { proxy } = useScriptCrisp()
// noop in development, ssr
// just works in production, client
function handleAction() {
proxy.$crisp.push(['do', 'chat:open'])
}
</script>
<template>
<div>
<button @click="handleAction">
Send Event
</button>
</div>
</template><ScriptCrisp>
The headless facade holds back the Crisp SDK until its element trigger fires. It listens for click by default.
Demo
Component API
See the Facade Component API for full props, events, and slots.
With environment variables
You can configure the Crisp website ID with an environment variable.
export default defineNuxtConfig({
scripts: {
registry: {
crisp: { trigger: 'onNuxtReady' },
}
},
// Public runtime config receives the environment variable.
runtimeConfig: {
public: {
scripts: {
crisp: {
id: '', // NUXT_PUBLIC_SCRIPTS_CRISP_ID
},
},
},
},
})
NUXT_PUBLIC_SCRIPTS_CRISP_ID=<YOUR_ID>
Events
The <ScriptCrisp> component emits ready after it mounts the chatbox and error if the script fails to load.
The current template checks status === 'loading' || !isReady before its error branch, so the named #error slot is unreachable. Listen for @error and render fallback UI outside the component until that ordering bug is fixed.
const emits = defineEmits<{
ready: [crisp: ReturnType<typeof useScriptCrisp>]
error: []
}>()
<script setup lang="ts">
function onReady(crisp) {
console.log('Crisp is ready', crisp)
}
</script>
<template>
<ScriptCrisp id="YOUR_ID" @ready="onReady" />
</template>
Slots
awaitingLoad
This slot displays content while Crisp waits for its configured trigger.
<template>
<ScriptCrisp id="YOUR_ID">
<template #awaitingLoad>
<div style="width: 54px; height: 54px; border-radius: 54px; cursor: pointer; background-color: #1972F5;">
chat!
</div>
</template>
</ScriptCrisp>
</template>
loading
This slot displays content while Crisp is loading.
ScriptLoadingIndicator provides the module's standard accessible loading state.
<template>
<ScriptCrisp id="YOUR_ID">
<template #loading>
<div class="bg-blue-500 text-white p-5">
Loading...
</div>
</template>
</ScriptCrisp>
</template>
useScriptCrisp()
Use useScriptCrisp() when you need to call Crisp without the launcher component.
export function useScriptCrisp<T extends CrispApi>(_options?: CrispInput) {}
See Registry Scripts for trigger and loading options, and the Crisp API documentation for available commands.
idstring required The Crisp ID.
runtimeConfigobjectExtra configuration options. Used to configure the locale. Same as CRISP_RUNTIME_CONFIG.
tokenIdstringAssociated a session, equivalent to using CRISP_TOKEN_ID variable. Same as CRISP_TOKEN_ID.
cookieDomainstringRestrict the domain that the Crisp cookie is set on. Same as CRISP_COOKIE_DOMAIN.
cookieExpirynumberThe cookie expiry in seconds. Same as CRISP_COOKIE_EXPIRATION.
Example
Call Crisp through the proxy:
<script setup lang="ts">
const { proxy } = useScriptCrisp({
id: 'YOUR_ID'
})
proxy.set('user:nickname', 'Harlan')
proxy.do('chat:open')
</script>