Docs
Nuxt Integration Guide
Add Heyo live chat to your Nuxt application with SSR support for Nuxt 2, 3, and Bridge.
This guide shows you how to add Heyo to your Nuxt application. Compatible with Nuxt 2, Nuxt 3, and Nuxt Bridge.
Installation
Method 1: JavaScript SDK Plugin (Recommended)
Install the SDK:
npm install @heyo.so/js
Create a plugin plugins/heyo.client.ts:
import HEYO from '@heyo.so/js'; // or: import { HEYO } from '@heyo.so/js'
export default defineNuxtPlugin(() => {
if (process.client) {
HEYO.init({ projectId: 'YOUR_PROJECT_ID' });
}
});
Method 2: Script Tag in app.vue
Add the Heyo script to your app.vue:
<template>
<div>
<NuxtPage />
</div>
</template>
<script setup>
useHead({
script: [
{
src: 'https://heyo.so/embed/script',
defer: true,
'data-project-id': 'YOUR_PROJECT_ID',
},
],
});
</script>
Method 3: Script Tag via Plugin
Create plugins/heyo.client.ts:
export default defineNuxtPlugin(() => {
useHead({
script: [
{
src: 'https://heyo.so/embed/script',
defer: true,
'data-project-id': 'YOUR_PROJECT_ID',
},
],
});
});
Advanced Usage
Create a Composable
Create composables/use-chat.ts:
export const useChat = () => {
const showChat = () => {
if (process.client && window.HEYO) {
window.HEYO.show();
}
};
const hideChat = () => {
if (process.client && window.HEYO) {
window.HEYO.hide();
}
};
const toggleChat = () => {
if (process.client && window.HEYO) {
window.HEYO.toggle();
}
};
return {
showChat,
hideChat,
toggleChat,
};
};
Usage in any component:
<template>
<button @click="showChat">Open Support Chat</button>
</template>
<script setup>
const { showChat } = useChat();
</script>
Pass User Data from Nuxt Auth
// plugins/heyo.client.ts
import HEYO from '@heyo.so/js'; // or: import { HEYO } from '@heyo.so/js'
export default defineNuxtPlugin(() => {
const user = useUser(); // or however you access user data
if (process.client) {
HEYO.init({
projectId: 'YOUR_PROJECT_ID',
user: user.value
? {
name: user.value.name,
email: user.value.email,
}
: undefined,
});
}
});
Control Widget Based on Route
<script setup>
const route = useRoute();
watch(
() => route.path,
(newPath) => {
if (process.client) {
// Hide on checkout pages
if (newPath.includes('/checkout')) {
window.HEYO?.hide();
} else {
window.HEYO?.show();
}
}
}
);
</script>
Environment-Based Project ID
Use runtime config for different environments:
// nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
public: {
heyoProjectId: process.env.HEYO_PROJECT_ID || 'YOUR_PROJECT_ID',
},
},
});
// plugins/heyo.client.ts
import HEYO from '@heyo.so/js'; // or: import { HEYO } from '@heyo.so/js'
export default defineNuxtPlugin(() => {
const config = useRuntimeConfig();
if (process.client) {
HEYO.init({ projectId: config.public.heyoProjectId });
}
});
SSR Considerations
Heyo is a client-side widget, so:
- Always use
.client.tssuffix for plugins - Check for
process.clientbefore accessingwindow.HEYO - Use
useHeadin components that might render server-side - The widget will load after hydration
TypeScript Support
Add type definitions to types.ts or create types/heyo.d.ts:
declare global {
interface Window {
HEYO: {
init: (config: { projectId: string; user?: any }) => void;
show: () => void;
hide: () => void;
toggle: () => void;
};
}
}
export {};
Best Practices
- Use a
.clientplugin to avoid SSR issues - Store the project ID in runtime config or
.env - Create a composable for reusable chat controls
- Use Nuxt's auto-imports for cleaner code
- Leverage
useHeadfor adding scripts
Troubleshooting
Widget not showing
Make sure your plugin has the .client suffix and is loading client-side only.
Type errors
Add the TypeScript definitions to your types directory.
Multiple instances
Ensure you're only initializing Heyo once, preferably in a plugin.
SSR errors
Always check process.client before accessing browser APIs like window.