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
@readyWidget initialized
@openChat window opened
@closeChat 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