Yak Docs
SDKs

Next.js SDK

The @yak-io/nextjs package provides the best experience for Next.js applications with automatic route scanning, a CLI for production builds, and App Router integration.

Prerequisites

  • Next.js 14+ (App Router)
  • React 18+
  • Node.js 18+
  • A Yak app ID (from your dashboard)

Installation

npm install @yak-io/nextjs
pnpm add @yak-io/nextjs
yarn add @yak-io/nextjs
bun add @yak-io/nextjs

Quick Start

Configure environment

Add your app ID to .env.local:

NEXT_PUBLIC_YAK_APP_ID=yak_app_123

Add the API handler

Create a catch-all route that serves configuration and handles tool calls:

// app/api/yak/[[...yak]]/route.ts
import { createNextYakHandler } from "@yak-io/nextjs/server";

export const { GET, POST } = createNextYakHandler();

Wrap your layout

Add YakProvider and YakWidget to your root layout:

// app/layout.tsx
import { YakProvider, YakWidget } from "@yak-io/nextjs/client";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        <YakProvider appId={process.env.NEXT_PUBLIC_YAK_APP_ID!}>
          {children}
          <YakWidget />
        </YakProvider>
      </body>
    </html>
  );
}

That's it — the widget appears in your app and can navigate users between pages.

Adding Tools

Pass tool adapters to expose your APIs to the AI assistant. Here's an example with tRPC:

// app/api/yak/[[...yak]]/route.ts
import { createNextYakHandler } from "@yak-io/nextjs/server";
import { createTRPCToolAdapter } from "@yak-io/trpc";
import { appRouter, createContext } from "@/server/trpc";

const trpcTools = createTRPCToolAdapter({
  router: appRouter,
  createContext: async ({ req }) => createContext({ req }),
  allowedProcedures: ["orders.list", "orders.detail", "products.search"],
});

export const { GET, POST } = createNextYakHandler({
  tools: [trpcTools],
});

See Tool Adapters for all available options including tRPC, GraphQL, REST/OpenAPI, and custom adapters.

Sourcing pages from a headless CMS instead of (or in addition to) the filesystem? See the Prismic adapter for a full Next.js example that composes with createNextYakHandler.

YakProvider Props

PropTypeDefaultDescription
appIdstringYour Yak application ID (required)
mode"chat" | "voice" | "both""chat"Which surfaces the trigger exposes. See Voice Mode.
getConfig() => Promise<ChatConfig>Fetches from /api/yakCustom config provider (used by chat and voice)
onToolCall(name, args) => Promise<unknown>POSTs to /api/yakCustom tool call handler (used by chat and voice)
themeThemeWidget styling options
onRedirect(path: string) => voidCustom navigation handler
disableRestartButtonbooleanfalseHide the restart button in the chat header
disablePageContentbooleanfalseStop 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.
user{ id, hash }Signed end-user identity. Enables conversation persistence and history.

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.

YakWidget Props

PropTypeDefaultDescription
mode"chat" | "voice" | "both"inherited from providerOverride the provider mode for this trigger
positionWidgetPosition"bottom-right"One of nine positions (e.g. "bottom-left", "top-center")
colorMode"light" | "dark" | "system"Force a color mode for the pill
lightButton / darkButton{ background?, color?, border? }Custom pill colors per mode

Next Steps

On this page