Yak Docs
SDKs

Nuxt SDK

The @yak-io/nuxt package provides a Nuxt 3-compatible provider for integrating Yak. It uses Vue refs for reactive state and exposes explicit mount()/destroy() methods for client-side lifecycle control via Nuxt plugins.

Installation

npm install @yak-io/nuxt @yak-io/javascript
pnpm add @yak-io/nuxt @yak-io/javascript
yarn add @yak-io/nuxt @yak-io/javascript
bun add @yak-io/nuxt @yak-io/javascript

Quick Start

Create a client-side Nuxt plugin

Create a .client.ts plugin to ensure the widget only runs in the browser:

// plugins/yak.client.ts
import { createYakProvider } from "@yak-io/nuxt";

export default defineNuxtPlugin((nuxtApp) => {
  const yak = createYakProvider({
    appId: "your-app-id",
    getConfig: async () => {
      const res = await $fetch("/api/yak");
      return res;
    },
    onToolCall: async (name, args) => {
      const res = await $fetch("/api/yak", {
        method: "POST",
        body: { name, args },
      });
      if (!res.ok) throw new Error(res.error);
      return res.result;
    },
  });

  nuxtApp.hook("app:mounted", () => yak.mount());

  // Provide to the app for use in composables
  return {
    provide: { yak },
  };
});

Set up server handlers

Use @yak-io/javascript to create the API endpoints. Create a Nitro server route:

// server/api/yak.get.ts
import { createYakHandler } from "@yak-io/javascript/server";

const { GET } = createYakHandler({
  routes: [
    { path: "/", title: "Home" },
    { path: "/products", title: "Products" },
  ],
});

export default defineEventHandler(async (event) => {
  const request = toWebRequest(event);
  const response = await GET(request);
  return response.json();
});
// server/api/yak.post.ts
import { createYakHandler } from "@yak-io/javascript/server";

const { POST } = createYakHandler({
  // ... same config
});

export default defineEventHandler(async (event) => {
  const request = toWebRequest(event);
  const response = await POST(request);
  return response.json();
});

API

createYakProvider

Creates a Yak widget instance with Vue-compatible readonly refs. Unlike the Vue SDK, the Nuxt SDK does not use Vue's provide/inject or lifecycle hooks — you manage the lifecycle explicitly through Nuxt plugins.

OptionTypeRequiredDescription
appIdstringYesYour Yak application ID
getConfig() => Promise<ChatConfig> | ChatConfigNoConfig provider for routes and tools
onToolCall(name, args) => Promise<unknown>NoHandler for tool execution
themeThemeNoWidget styling options
onRedirect(path: string) => voidNoCustom navigation handler
disableRestartButtonbooleanNoHide the restart button in the header
triggerboolean | TriggerButtonConfigNoConfigure the floating trigger button

Return value (YakApi)

PropertyTypeDescription
isOpenReadonly<Ref<boolean>>Whether the chat panel is currently open
isReadyReadonly<Ref<boolean>>Whether the widget iframe is ready
open() => voidOpen the chat panel
close() => voidClose the chat panel
openWithPrompt(prompt: string) => voidOpen and send a specific prompt
subscribeToToolEvents(handler) => () => voidSubscribe to tool call events (returns unsubscribe)
mount() => voidMount the widget DOM — call in app:mounted hook
destroy() => voidDestroy the widget DOM

Using in Components

Access the provider via useNuxtApp():

<script setup lang="ts">
const { $yak } = useNuxtApp();

function openChat() {
  $yak.open();
}
</script>

<template>
  <button @click="openChat">Open Chat</button>
  <p v-if="$yak.isOpen.value">Chat is open</p>
</template>

Tool Events

Subscribe to tool call completion events for UI synchronization:

<script setup lang="ts">
const { $yak } = useNuxtApp();

onMounted(() => {
  const unsubscribe = $yak.subscribeToToolEvents((event) => {
    if (event.ok && event.name.startsWith("order.")) {
      refreshNuxtData();
    }
  });

  onUnmounted(unsubscribe);
});
</script>

Router Integration

Pass Nuxt's navigateTo for client-side navigation:

// plugins/yak.client.ts
import { createYakProvider } from "@yak-io/nuxt";

export default defineNuxtPlugin(() => {
  const yak = createYakProvider({
    appId: "your-app-id",
    onRedirect: (path) => navigateTo(path),
    // ...other options
  });

  // ...
});

The .client.ts suffix ensures the plugin only runs in the browser, making YakEmbed instantiation SSR-safe.

On this page