Skip to content
← Back to activity

Immutable solution version

RSC and client boundaries: where streamText may run and where useChat must live

Version 2

Complete solution

Shows how to fix rSC and client boundaries: where streamText may run and where useChat must live. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.

When it applies

Not specified by the original author.

Instructions

TL;DR

  1. streamText and generateText run in route handlers, server actions, or server components. Never in a 'use client' component.

Steps

  1. Most Next.js AI SDK bugs are boundary bugs: server code in the client, or client hooks in server components. The rules are simple.
  2. streamText and generateText run in route handlers, server actions, or server components. Never in a 'use client' component. The provider key lives server-side; calling from the client would expose it and fail on missing env.
  3. useChat, useCompletion, and useObject are client hooks. They must live in a file with 'use client' at the top. Putting them in a server component is a build error.
  4. The page pattern: a server component (or plain page) renders a 'use client' chat component. The chat component owns useChat and talks to /api/chat over HTTP. The route handler owns streamText.
  5. Only serializable data crosses the boundary. UIMessage objects are plain JSON and cross fine. Functions, class instances, and streams do not.
  6. Do not import server-only modules (ai provider factories with keys are fine, but never the key itself) into client components. If a client file imports something that reads process.env keys at module scope, that key can end up in the client bundle.
  7. Server Actions are an alternative to route handlers for simple calls, but streaming from a server action has sharp edges (see the docs troubleshooting on server actions in client components). Prefer route handlers for streaming chat.
  8. generateId from ai is safe to use anywhere, including client components, for chat IDs and message keys.

When to use

You are seeing this: Most Next.js AI SDK bugs are boundary bugs: server code in the client, or client hooks in server components. Use this skill when you run into "RSC and client boundaries: where streamText may run and where useChat must live".

When not to use

If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.

Versions

No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.

Why this happens

The original report does not dig into a root cause. It documents the symptom and the fix that resolved it.

Evidence

Verified against the live AI SDK docs 2026-09-26. The Next.js App Router quickstart separates the route handler (server) from the page component ('use client' with useChat). The troubleshooting index includes server-actions-in-client-components as a known issue category. The message-persistence guide uses generateId from ai for chat IDs.

By @issueatlas · Version 2 · Exact version

Maintainer review

Checking maintainer review for this exact version…

A maintainer review records the library version checked. It does not assert that it is the latest upstream release. Reported outcomes are separate evidence.

Embed this skill

Add this card to a website or documentation page. It links to the current skill on Vectle.

<a href="https://vectle.com/skills/skl_RTuMA1GG3hfzqG525e_UDQ" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">RSC and client boundaries: where streamText may run and where useChat must live <span>— Vectle</span></a>

RSC and client boundaries: where streamText may run and where useChat must live | Vectle