Vue.js Integration
Integrate BotHarbor chat widget into your Vue.js applications with support for both Vue 2 and Vue 3.
Vue 3 Composition API
The recommended approach for Vue 3 applications using the modern Composition API.
Basic Setup
<template>
<div class="app">
<header>
<h1>My Vue App</h1>
<button @click="openChat" class="chat-button">
Need Help?
</button>
</header>
<main>
<p>Your app content here...</p>
</main>
</div>
</template>
<script setup>
import { onMounted, onUnmounted, ref } from 'vue'
const chatReady = ref(false)
const loadBotHarbor = () => {
return new Promise((resolve, reject) => {
if (window.BotHarbor) {
resolve(window.BotHarbor)
return
}
const script = document.createElement('script')
script.src = 'https://botharbor.ai/embed.js'
script.async = true
script.onload = () => resolve(window.BotHarbor)
script.onerror = reject
document.head.appendChild(script)
})
}
const initializeBotHarbor = async () => {
try {
const BotHarbor = await loadBotHarbor()
BotHarbor.init({
botId: import.meta.env.VITE_BOTHARBOR_BOT_ID,
theme: 'light',
position: 'bottom-right',
autoOpen: false,
onReady: () => {
chatReady.value = true
console.log('BotHarbor is ready')
}
})
} catch (error) {
console.error('Failed to load BotHarbor:', error)
}
}
const openChat = () => {
if (window.BotHarbor && chatReady.value) {
window.BotHarbor.open()
}
}
const closeChat = () => {
if (window.BotHarbor) {
window.BotHarbor.close()
}
}
onMounted(() => {
initializeBotHarbor()
})
onUnmounted(() => {
if (window.BotHarbor) {
window.BotHarbor.destroy()
}
})
</script>Vue 3 Composable
Create a reusable composable for better organization and reusability across components.
useBotHarbor Composable
// composables/useBotHarbor.js
import { ref, onMounted, onUnmounted } from 'vue'
export function useBotHarbor(config = {}) {
const isReady = ref(false)
const isOpen = ref(false)
const error = ref(null)
const defaultConfig = {
theme: 'light',
position: 'bottom-right',
autoOpen: false,
...config
}
const loadScript = () => {
return new Promise((resolve, reject) => {
if (window.BotHarbor) {
resolve(window.BotHarbor)
return
}
const script = document.createElement('script')
script.src = 'https://botharbor.ai/embed.js'
script.async = true
script.onload = () => resolve(window.BotHarbor)
script.onerror = () => reject(new Error('Failed to load BotHarbor script'))
document.head.appendChild(script)
})
}
const initialize = async () => {
try {
const BotHarbor = await loadScript()
BotHarbor.init({
...defaultConfig,
onReady: () => {
isReady.value = true
defaultConfig.onReady?.()
},
onOpen: () => {
isOpen.value = true
defaultConfig.onOpen?.()
},
onClose: () => {
isOpen.value = false
defaultConfig.onClose?.()
},
onError: (err) => {
error.value = err
defaultConfig.onError?.(err)
}
})
} catch (err) {
error.value = err
console.error('BotHarbor initialization failed:', err)
}
}
const open = () => {
if (window.BotHarbor && isReady.value) {
window.BotHarbor.open()
}
}
const close = () => {
if (window.BotHarbor) {
window.BotHarbor.close()
}
}
const sendMessage = (message) => {
if (window.BotHarbor && isReady.value) {
window.BotHarbor.sendMessage(message)
}
}
const setUser = (user) => {
if (window.BotHarbor && isReady.value) {
window.BotHarbor.setUser(user)
}
}
onMounted(() => {
initialize()
})
onUnmounted(() => {
if (window.BotHarbor) {
window.BotHarbor.destroy()
}
})
return {
isReady,
isOpen,
error,
open,
close,
sendMessage,
setUser
}
}Using the Composable
<template>
<div class="app">
<header>
<h1>My Vue App</h1>
<div class="chat-controls">
<button
@click="open"
:disabled="!isReady"
class="btn btn-primary"
>
{{ isReady ? 'Open Chat' : 'Loading...' }}
</button>
<button
@click="close"
:disabled="!isOpen"
class="btn btn-secondary"
>
Close Chat
</button>
</div>
<div v-if="error" class="error">
Error: {{ error.message }}
</div>
</header>
<main>
<p>Chat status: {{ isOpen ? 'Open' : 'Closed' }}</p>
</main>
</div>
</template>
<script setup>
import { useBotHarbor } from '@/composables/useBotHarbor'
const { isReady, isOpen, error, open, close, sendMessage, setUser } = useBotHarbor({
botId: import.meta.env.VITE_BOTHARBOR_BOT_ID,
theme: 'auto',
position: 'bottom-right',
onReady: () => {
console.log('Chat is ready!')
// Set user information when chat is ready
setUser({
name: 'John Doe',
email: 'john@example.com'
})
}
})
</script>Vue 2 Options API
For Vue 2 applications using the traditional Options API approach.
<template>
<div class="app">
<header>
<h1>My Vue 2 App</h1>
<button @click="openChat" :disabled="!chatReady">
{{ chatReady ? 'Open Chat' : 'Loading Chat...' }}
</button>
</header>
<main>
<p>Your app content here...</p>
</main>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
chatReady: false,
chatOpen: false
}
},
async mounted() {
await this.initializeBotHarbor()
},
beforeDestroy() {
if (window.BotHarbor) {
window.BotHarbor.destroy()
}
},
methods: {
loadBotHarborScript() {
return new Promise((resolve, reject) => {
if (window.BotHarbor) {
resolve(window.BotHarbor)
return
}
const script = document.createElement('script')
script.src = 'https://botharbor.ai/embed.js'
script.async = true
script.onload = () => resolve(window.BotHarbor)
script.onerror = reject
document.head.appendChild(script)
})
},
async initializeBotHarbor() {
try {
const BotHarbor = await this.loadBotHarborScript()
BotHarbor.init({
botId: process.env.VUE_APP_BOTHARBOR_BOT_ID,
theme: 'light',
position: 'bottom-right',
autoOpen: false,
onReady: () => {
this.chatReady = true
console.log('BotHarbor is ready')
},
onOpen: () => {
this.chatOpen = true
},
onClose: () => {
this.chatOpen = false
}
})
} catch (error) {
console.error('Failed to initialize BotHarbor:', error)
}
},
openChat() {
if (window.BotHarbor && this.chatReady) {
window.BotHarbor.open()
}
},
closeChat() {
if (window.BotHarbor) {
window.BotHarbor.close()
}
}
}
}
</script>Environment Configuration
Configure your Vue application with environment variables for different deployment environments.
Environment Files
# .env.local (Vue 3 with Vite)
VITE_BOTHARBOR_BOT_ID=your-bot-id-here
VITE_BOTHARBOR_THEME=light
VITE_BOTHARBOR_POSITION=bottom-right
# .env.local (Vue 2 with Vue CLI)
VUE_APP_BOTHARBOR_BOT_ID=your-bot-id-here
VUE_APP_BOTHARBOR_THEME=light
VUE_APP_BOTHARBOR_POSITION=bottom-rightBest Practices
Performance Optimization
- ✓Use async script loading to prevent blocking
- ✓Initialize BotHarbor in mounted/onMounted lifecycle
- ✓Clean up resources in beforeDestroy/onUnmounted
- ✓Use composables for reusable logic (Vue 3)
