Core Concepts
This page explains the core concepts you'll work with when integrating Yak.
Routes
Routes tell the AI what pages exist in your application. When a user asks "take me to the settings page," the AI uses the route manifest to navigate them there.
const routes = [
{ path: "/", title: "Home" },
{ path: "/settings", title: "Settings", description: "Manage your account" },
{ path: "/products", title: "Products" },
];Each route has:
path– The URL pathtitle– Human-readable name (optional)description– Optional context for the AI
For Next.js, routes are automatically scanned from your app/ directory with metadata extracted from page files. For other frameworks, you provide them manually or use a route source.
Tools
Tools are actions the AI can invoke on behalf of users. When a user asks "show me my recent orders," the AI calls the appropriate tool and displays the results.
const tools = [
{
name: "orders.list",
description: "List orders for the current user",
input_schema: {
type: "object",
properties: {
limit: { type: "number", default: 10 },
status: { type: "string", enum: ["pending", "shipped", "delivered"] },
},
},
},
];Each tool has:
name– Unique identifierdescription– What the tool does (helps the AI decide when to use it)input_schema– JSON Schema defining the tool's parameters
Tool Adapters
Tool adapters connect your existing APIs and data sources to Yak. Instead of manually defining tools, adapters introspect your code and generate tool definitions automatically.
// tRPC adapter - all procedures by default
const trpcTools = createTRPCToolAdapter({
router: appRouter,
// Optionally restrict procedures
disallowedProcedures: ["admin.deleteUser"],
});
// Or define inline
const customTools = {
id: "custom",
getTools: async () => [...],
executeTool: async (name, args) => {...},
};Available adapters:
- tRPC Adapter – Expose tRPC procedures as tools
- GraphQL – Schema-based GraphQL integration
- REST/OpenAPI – OpenAPI spec-based REST integration
- Custom – Build your own adapter
Server Handlers
Server handlers are API endpoints that respond to the widget:
- GET – Returns the chat configuration (routes + tool manifest)
- POST – Executes tool calls
import { createYakHandler } from "@yak-io/javascript/server";
export const { GET, POST } = createYakHandler({
routes: [...],
tools: [...],
});The handlers work with any Fetch-compatible runtime (Next.js, Cloudflare Workers, Deno, Bun, etc.).
Client Components
The client side consists of two components:
YakProvider
Wraps your application and manages widget state, configuration, and 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", body: JSON.stringify({ name, args }) });
return res.json();
}}
>
{children}
</YakProvider>YakWidget
Renders the floating chat button and iframe panel:
<YakWidget triggerLabel="Ask AI" />Programmatic Control
Control the widget from your code using the useYak hook:
const { open, close, openWithPrompt, isOpen } = useYak();
// Open the widget
open();
// Open with a specific question
openWithPrompt("How do I reset my password?");This enables contextual help buttons, keyboard shortcuts, and integration with your application's workflows.
Request Flow
Here's how a typical interaction flows through the system:
- User clicks the chat widget
- Widget loads and fetches config via
getConfig()→ GET/api/yak - User asks a question
- AI processes the question with route and tool context
- AI decides to call a tool
- Widget calls
onToolCall()→ POST/api/yak - Server handler routes the call to the correct tool adapter
- Tool executes and returns result
- AI formats and displays the response
The iframe communicates with your application via postMessage. Your handlers execute tool calls in your server context with full access to your authentication and data layer.