Skip to main content

Vue 2 Integration

Integrate Ozwell into your Vue 2 application with the Options API pattern.

Installation​

npm install @ozwell/vue2
# or
yarn add @ozwell/vue2

Quick Start​

Register the plugin globally:

// main.js
import Vue from 'vue';
import OzwellPlugin from '@ozwell/vue2';
import App from './App.vue';

Vue.use(OzwellPlugin, {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
});

new Vue({
render: h => h(App),
}).$mount('#app');

Use the component anywhere:

<template>
<div>
<h1>My App</h1>
<ozwell-chat />
</div>
</template>

Option 2: Local Component Registration​

<template>
<div>
<h1>My App</h1>
<ozwell-chat
:api-key="apiKey"
:agent-id="agentId"
theme="auto"
/>
</div>
</template>

<script>
import { OzwellChat } from '@ozwell/vue2';

export default {
name: 'App',
components: {
OzwellChat,
},
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
};
},
};
</script>

Component API​

<ozwell-chat />​

<template>
<ozwell-chat
:api-key="apiKey"
:agent-id="agentId"
theme="auto"
position="bottom-right"
primary-color="#4f46e5"
width="400px"
height="600px"
:auto-open="false"
greeting="Hello! How can I help?"
placeholder="Type a message..."
:context="context"
@ready="onReady"
@open="onOpen"
@close="onClose"
@user-share="onUserShare"
@error="onError"
/>
</template>

Props​

PropTypeDefaultDescription
apiKeyStringrequiredScoped API key
agentIdStringrequiredAgent ID
themeString'auto''light', 'dark', or 'auto'
positionString'bottom-right''bottom-right' or 'bottom-left'
primaryColorString'#4f46e5'Accent color
widthString'400px'Chat window width
heightString'600px'Chat window height
autoOpenBooleanfalseOpen on mount
greetingStringAgent defaultInitial message
placeholderString'Type a message...'Input placeholder
contextObject{}Context data for agent

Events​

EventPayloadDescription
@ready—Widget initialized
@open—Chat window opened
@close—Chat window closed
@user-shareunknownUser explicitly shared data
@errorOzwellErrorError occurred

Privacy Note: There is no @message event. Conversation content is private between the user and Ozwell. The @user-share event only fires when the user explicitly chooses to share data.


Instance Methods​

Access the Ozwell instance via $ozwell:

<template>
<div>
<button @click="openChat">Open Chat</button>
<button @click="closeChat">Close Chat</button>
<button @click="sendHello">Send Hello</button>

<ozwell-chat :api-key="apiKey" :agent-id="agentId" />
</div>
</template>

<script>
export default {
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
};
},
methods: {
openChat() {
this.$ozwell.open();
},
closeChat() {
this.$ozwell.close();
},
sendHello() {
this.$ozwell.sendMessage('Hello!');
},
},
};
</script>

Available Methods​

MethodArgumentsDescription
open()—Open the chat window
close()—Close the chat window
toggle()—Toggle open/closed
sendMessage(content)stringSend a message
setContext(context)objectUpdate context data

Reactive Properties​

PropertyTypeDescription
$ozwell.isReadybooleanWidget initialized
$ozwell.isOpenbooleanChat window open

Examples​

With Vue Router Context​

<template>
<ozwell-chat
:api-key="apiKey"
:agent-id="agentId"
:context="context"
/>
</template>

<script>
export default {
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
};
},
computed: {
context() {
return {
page: this.$route.path,
query: this.$route.query,
timestamp: Date.now(),
};
},
},
};
</script>

With Vuex Store​

<template>
<ozwell-chat
:api-key="apiKey"
:agent-id="agentId"
:context="context"
@open="onOpen"
@close="onClose"
@user-share="onUserShare"
/>
</template>

<script>
import { mapState, mapMutations } from 'vuex';

export default {
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
};
},
computed: {
...mapState('user', ['user']),
context() {
return {
userId: this.user?.id,
email: this.user?.email,
};
},
},
methods: {
...mapMutations('chat', ['SET_OPEN']),
onOpen() {
this.SET_OPEN(true);
},
onClose() {
this.SET_OPEN(false);
},
onUserShare(data) {
// Only fires when user explicitly shares
console.log('User shared:', data);
},
},
};
</script>

Custom Trigger Button​

<template>
<div>
<button
v-if="!$ozwell.isOpen"
@click="$ozwell.open()"
class="chat-trigger"
>
💬 Need help?
</button>

<ozwell-chat
:api-key="apiKey"
:agent-id="agentId"
:show-trigger="false"
/>
</div>
</template>

<script>
export default {
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
};
},
};
</script>

<style scoped>
.chat-trigger {
position: fixed;
bottom: 20px;
right: 20px;
padding: 12px 24px;
background: #4f46e5;
color: white;
border: none;
border-radius: 24px;
cursor: pointer;
}
</style>

Conditional Rendering by Route​

<template>
<ozwell-chat
v-if="showChat"
:api-key="apiKey"
:agent-id="agentId"
/>
</template>

<script>
export default {
data() {
return {
apiKey: process.env.VUE_APP_OZWELL_API_KEY,
agentId: process.env.VUE_APP_OZWELL_AGENT_ID,
hiddenRoutes: ['/checkout', '/auth', '/admin'],
};
},
computed: {
showChat() {
return !this.hiddenRoutes.some(route =>
this.$route.path.startsWith(route)
);
},
},
};
</script>

Nuxt 2​

For Nuxt 2, create a plugin:

// plugins/ozwell.client.js
import Vue from 'vue';
import OzwellPlugin from '@ozwell/vue2';

export default function ({ $config }) {
Vue.use(OzwellPlugin, {
apiKey: $config.ozwellApiKey,
agentId: $config.ozwellAgentId,
});
}
// nuxt.config.js
export default {
plugins: [
{ src: '~/plugins/ozwell.client.js', mode: 'client' },
],
publicRuntimeConfig: {
ozwellApiKey: process.env.OZWELL_API_KEY,
ozwellAgentId: process.env.OZWELL_AGENT_ID,
},
};

TypeScript​

For TypeScript projects, add type declarations:

// shims-ozwell.d.ts
import Vue from 'vue';

declare module 'vue/types/vue' {
interface Vue {
$ozwell: {
isReady: boolean;
isOpen: boolean;
open(): void;
close(): void;
toggle(): void;
sendMessage(content: string): void;
setContext(context: Record<string, unknown>): void;
};
}
}

Migration to Vue 3​

When upgrading to Vue 3:

  1. Replace @ozwell/vue2 with @ozwell/vue
  2. Use Composition API patterns (useOzwell() composable)
  3. Update plugin registration syntax
  4. Replace this.$ozwell with composable calls

See Vue 3 Integration for details.


Troubleshooting​

Widget Not Appearing​

  1. Check that Vue plugin is registered before app mount
  2. Verify API key and agent ID are correct
  3. Check browser console for errors

$ozwell is undefined​

Ensure the plugin is registered:

// ✅ Correct order
Vue.use(OzwellPlugin, { ... });
new Vue({ ... }).$mount('#app');

// ❌ Wrong order
new Vue({ ... }).$mount('#app');
Vue.use(OzwellPlugin, { ... });

Context Not Updating​

Use computed properties for reactive context:

// ✅ Reactive
computed: {
context() {
return { page: this.$route.path };
}
}

// ❌ Static
data() {
return {
context: { page: this.$route.path }
};
}

Next Steps​