Yak Docs
Chat Integration

React

The @yak-io/react package provides React components and hooks for integrating Yak into any React application.

For Next.js applications, use @yak-io/nextjs instead for automatic route scanning and better integration.

Installation

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

Quick Start

Add the Provider and Widget

// App.tsx
import { YakProvider, YakWidget } from "@yak-io/react";

export default function App() {
  return (
    <YakProvider
      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;
      }}
    >
      {/* Your app content */}
      <YakWidget />
    </YakProvider>
  );
}

Set up server handlers

Use @yak-io/javascript to create the API endpoints. See Server Handlers for runtime-specific examples.

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

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

Components

YakProvider

The context provider managing widget state and iframe communication.

<YakProvider
  appId="your-app-id"
  getConfig={async () => fetch("/api/yak").then(r => r.json())}
  onToolCall={async (name, args) => {
    const res = await fetch("/api/yak", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name, args }),
    });
    return res.json();
  }}
  theme={{ position: "right" }}
  onRedirect={(path) => navigate(path)}
>
  {children}
</YakProvider>

Props

PropTypeRequiredDescription
appIdstringYour Yak application ID
getConfig() => Promise<ChatConfig>Provider for routes/tools config
onToolCall(name, args) => Promise<unknown>Handler for tool execution
themeThemeWidget theming options
onRedirect(path: string) => voidCustom navigation handler
disableRestartButtonbooleanHide the restart session button in the header

YakWidget

Renders the floating chat button and iframe panel.

<YakWidget 
  iframeClassName="custom-iframe-class"
  triggerLabel="Ask AI"
/>

Hooks

useYak

Access the widget API from any component:

import { useYak } from "@yak-io/react";

export function ChatButton() {
  const { open, close, openWithPrompt, isOpen } = useYak();

  return (
    <div>
      <button onClick={() => open()}>Open Chat</button>
      <button onClick={() => openWithPrompt("Help me with this page")}>
        Get Help
      </button>
      {isOpen && (
        <button onClick={() => close()}>Close</button>
      )}
    </div>
  );
}

Return Value

PropertyTypeDescription
open() => voidOpen the chat panel
close() => voidClose the chat panel
openWithPrompt(prompt: string) => voidOpen with a pre-filled prompt
isOpenbooleanCurrent open/closed state

useYakToolEvent

Subscribe to tool call completion events for page-level cache invalidation. This is useful when the chatbot modifies data via tool calls and you need to refresh specific UI components.

import { useYakToolEvent } from "@yak-io/react";

function OrderPage({ orderId }: { orderId: string }) {
  const queryClient = useQueryClient();
  
  useYakToolEvent((event) => {
    // Invalidate cache when order-related tools are called
    if (event.ok && event.name.startsWith("order.")) {
      queryClient.invalidateQueries({ queryKey: ["order", orderId] });
    }
  });
  
  return <OrderDetails orderId={orderId} />;
}

Event Object

PropertyTypeDescription
namestringThe tool name that was called (e.g., "order.cancel")
argsunknownThe arguments passed to the tool
okbooleanWhether the call succeeded
resultunknownThe result (if ok is true)
errorstringThe error message (if ok is false)

The hook automatically unsubscribes when the component unmounts, making it safe for page-specific invalidation.

The onRedirect prop integrates with your router:

// React Router
import { useNavigate } from "react-router-dom";

function App() {
  const navigate = useNavigate();
  
  return (
    <YakProvider onRedirect={(path) => navigate(path)} {...props}>
      {children}
    </YakProvider>
  );
}

// TanStack Router
<YakProvider onRedirect={(path) => router.navigate({ to: path })} />

// Full reload (default)
<YakProvider onRedirect={(path) => window.location.href = path} />

Styling

Customize the widget position, color mode, and display mode:

<YakProvider
  theme={{
    position: "right", // or "left"
    colorMode: "system", // "light", "dark", or "system"
    displayMode: "chatbox", // "chatbox" (floating panel) or "drawer" (side panel)
  }}
  {...props}
>
  <YakWidget triggerLabel="Chat with AI" />
</YakProvider>

For drawer mode, the position controls which side the drawer appears on ("right" → right side, "left" → left side).

See Styling for display modes and CSS variable customization.

TypeScript

The package is fully typed:

import { useYak } from "@yak-io/react";
import type { YakConfig, YakMessage } from "@yak-io/react";

function MyComponent() {
  const { 
    openWidget, 
    closeWidget, 
    openWithPrompt, 
    isWidgetOpen,
    config,      // YakConfig | null
    sendMessage, // (message: YakMessage) => void
  } = useYak();
}

On this page