Next.js App Router · @serpkite/ai-sdk
Next.js + SerpKite
Build a Next.js chatbot that searches Google before it answers: one route handler with streamText and serpkiteTools(), useChat on the client, and your API key never leaves the server.
Overview
What Next.js is, and where SerpKite fits
Next.js route handlers and server actions run on the server, which is where the SerpKite key belongs. The AI SDK streams the model's answer, including each tool call, to the browser.
@serpkite/ai-sdk gives the model search, news, maps, webpage, extract and crawl tools. Its client reads SERPKITE_API_KEY on the first call, so the module-level tool set doesn't break next build.
Setup
Set it up in 4 steps
-
1
Get an API key
Sign up (no card) and create a key in the dashboard. Put it in
.env.localand in your Vercel project's environment variables. Never prefix it withNEXT_PUBLIC_.SERPKITE_API_KEY=skt_live_… OPENAI_API_KEY=sk-… -
2
Install
Tools, the AI SDK core and React hooks, a model provider and zod.
npm install @serpkite/ai-sdk ai @ai-sdk/react @ai-sdk/openai zod -
3
Add the route handler
app/api/chat/route.tsstreams the answer.maxDurationgives the model time to search and read a page or two. -
4
Render the chat
useChatposts to/api/chatby default. Tool calls arrive astool-<name>parts, so you can show what the model searched for.
Code
Complete example
import { openai } from "@ai-sdk/openai";
import { serpkiteTools } from "@serpkite/ai-sdk";
import { convertToModelMessages, stepCountIs, streamText, type UIMessage } from "ai";
export const maxDuration = 60;
const tools = serpkiteTools({ only: ["search", "news", "webpage"] });
export async function POST(req: Request) {
const { messages }: { messages: UIMessage[] } = await req.json();
const result = streamText({
model: openai("gpt-5-mini"),
system: "Search the web before answering questions about current facts. Cite the URLs you used.",
messages: await convertToModelMessages(messages),
tools,
stopWhen: stepCountIs(5),
});
return result.toUIMessageStreamResponse();
}Server actions
No chat UI? Call it from a server action
A server action can run the same tools with generateText and return the answer to a form or a server component.
"use server";
import { openai } from "@ai-sdk/openai";
import { serpkiteTools } from "@serpkite/ai-sdk";
import { generateText, stepCountIs } from "ai";
const tools = serpkiteTools({ only: ["search", "webpage"] });
export async function research(question: string) {
const { text } = await generateText({
model: openai("gpt-5-mini"),
tools,
stopWhen: stepCountIs(5),
prompt: question,
});
return text;
}Runtime
Edge, caching and long crawls
Add export const runtime = "edge" to the route to run it on the edge; both packages only use fetch.
To save credits on repeated questions, pin fixed: { max_age: 3600 } on a tool: cached results within that age cost half.
crawl returns a task id by default, and the model polls it with crawl_result. serpkiteCrawl({ wait: true }) waits for the pages instead; raise maxDuration first, since a crawl can run for minutes.
Keep the key on the server
Import `@serpkite/ai-sdk` only in route handlers, server actions and server components. A client component would bundle your key into the browser.
FAQ
Next.js and SerpKite: common questions
Keep exploring
Related APIs and integrations
Start building
Give your Next.js project Google search
2,500 free credits, then 1,000 every month. No credit card.