Vue SDK
The @yak-io/vue package provides Vue 3 composables for integrating Yak into any Vue application. It uses Vue's provide/inject system and lifecycle hooks for automatic setup and cleanup.
Installation
npm install @yak-io/vue @yak-io/javascriptpnpm add @yak-io/vue @yak-io/javascriptyarn add @yak-io/vue @yak-io/javascriptbun add @yak-io/vue @yak-io/javascriptQuick Start
Set up the provider in your root component
Call createYakProvider in your root component's <script setup>. It mounts the widget when the component is mounted and cleans up on unmount.
<!-- App.vue -->
<script setup lang="ts">
import { createYakProvider } from "@yak-io/vue";
createYakProvider({
appId: "your-app-id",
getConfig: async () => {
const res = await fetch("/api/yak");
return res.json();
},
onToolCall: async (name, args) => {
const res = await fetch("/api/yak", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, args }),
});
const data = await res.json();
if (!data.ok) throw new Error(data.error);
return data.result;
},
});
</script>
<template>
<router-view />
</template>Set up server handlers
Use @yak-io/javascript to create the API endpoints on your backend. See the JavaScript SDK for runtime-specific examples (Express, Hono, Cloudflare Workers, etc.).
// api/yak.ts
import { createYakHandler } from "@yak-io/javascript/server";
export const { GET, POST } = createYakHandler({
routes: [
{ path: "/", title: "Home" },
{ path: "/products", title: "Products" },
],
});Composables
createYakProvider
Sets up the Yak widget and provides it to descendant components via Vue's provide/inject. Call this once in a root or layout component.
The widget automatically mounts on onMounted and destroys on onUnmounted.
| Option | Type | Required | Description |
|---|---|---|---|
appId | string | Yes | Your Yak application ID |
mode | "chat" | "voice" | "both" | No | Which surfaces the trigger exposes. Defaults to "chat". See Voice Mode. |
getConfig | () => Promise<ChatConfig> | ChatConfig | No | Config provider for routes and tools (used by chat and voice) |
onToolCall | (name, args) => Promise<unknown> | No | Handler for tool execution (used by chat and voice) |
theme | Theme | No | Widget styling options |
onRedirect | (path: string) => void | No | Custom navigation handler |
disableRestartButton | boolean | No | Hide the restart button in the header |
disablePageContent | boolean | No | Stop sending any page context (URL, title, and visible text) to the assistant. The widget still works, but it won't be aware of the page the user is on. |
trigger | boolean | TriggerButtonConfig | No | Configure the floating trigger button |
user | { id, hash } | No | Signed end-user identity. Enables conversation persistence and history. Call setUser() to change it after setup (login/logout). |
Privacy: By default Yak shares the current page's URL, title, and visible text with the assistant so it can answer questions about the page the user is viewing. Set disablePageContent to turn this off entirely — the SDK then sends nothing about the page (not even the URL), so the assistant can't answer page-specific questions.
Returns a YakApi object (also injected into the component tree).
useYak
Access widget controls from any descendant component:
<script setup lang="ts">
import { useYak } from "@yak-io/vue";
const { open, close, openWithPrompt, isOpen } = useYak();
</script>
<template>
<button @click="open()">Open Chat</button>
<button @click="openWithPrompt('Help me with this page')">Get Help</button>
<button v-if="isOpen" @click="close()">Close</button>
</template>| Property | Type | Description |
|---|---|---|
isOpen | Readonly<Ref<boolean>> | Whether the chat panel is currently open |
isReady | Readonly<Ref<boolean>> | Whether the widget iframe is ready |
chatLoading | Readonly<Ref<boolean>> | isOpen && !isReady — opening but not yet interactive |
open | () => void | Open the chat panel |
close | () => void | Close the chat panel |
openWithPrompt | (prompt: string) => void | Open and send a specific prompt |
subscribeToToolEvents | (handler) => () => void | Subscribe to tool call events (returns unsubscribe) |
voiceMachine | Readonly<Ref<VoiceMachine>> | Current voice state (state, optional errorMessage) |
voiceLoading | Readonly<Ref<boolean>> | true while the voice session is connecting |
voiceStart | () => Promise<void> | Start a voice session — see Voice Mode |
voiceStop | () => Promise<void> | Stop the current voice session |
voiceToggle | () => Promise<void> | Start if idle/error, stop if active |
setUser | (user?: { id, hash }) => void | Set or clear the signed end-user identity after setup — call on login/logout |
isOpen and isReady are readonly Vue refs — use .value in scripts and unwrap automatically in templates.
useYakToolEvent
Subscribe to tool call completion events — automatically cleans up on component unmount. Useful for keeping your UI in sync with agent actions:
<script setup lang="ts">
import { useYakToolEvent } from "@yak-io/vue";
useYakToolEvent((event) => {
if (event.ok && event.name.startsWith("order.")) {
refreshOrders();
}
});
</script>See UI Synchronization for more details.
Router Integration
Pass Vue Router's navigation function to onRedirect for client-side navigation:
<script setup lang="ts">
import { useRouter } from "vue-router";
import { createYakProvider } from "@yak-io/vue";
const router = useRouter();
createYakProvider({
appId: "your-app-id",
onRedirect: (path) => router.push(path),
// ...other options
});
</script>