A server action is a Next.js server-side function that a client component can call directly. For an AI chat, it can accept a user message and conversation history, call an AI provider, and return a response without a separate API route. Keeping AI processing on the server can reduce client code and keep sensitive processing there. section 4.1.2 section 4.1.1
Listing 4.1 Server action that creates a streamable conversation
'use server'; #1
import { streamText } from 'ai';
import { createStreamableValue } from 'ai/rsc'; #2
export async function
continueConversation(history, provider, model) {
'use server';
const supportedModel = getSupportedModel(provider, model);
const stream = createStreamableValue(); #3
(async () => {
const { textStream } = await streamText({
model: supportedModel,
system: "I'm happy to assist you in any way I can.
How can I be of service today?",
messages: history,
});
for await (const text of textStream) { #4
stream.update(text);
}
stream.done();
})();
return { #5
messages: history,
newMessage: stream.value,
};
}
The server-side chat action accepts history, provider, and model; starts a text stream; updates a streamable value for each chunk; and returns that value with the message history. section 4.1.2
In the client form handler, prevent the default submission, ignore empty input, and add the user's message to the displayed conversation. Call the action with the updated history, then iterate over `readStreamableValue(newMessage)` to display the reply as it arrives. This replaces the example's `useChat` API-route flow while preserving an interactive chat UI. section 4.1.3
Run the streaming chat
From the project repository root, run `npm run dev -w ch04/chat-rsc`. Configure the example's provider secret in `.env`, shown as `GEMINI_API_KEY=<SECRET_KEY>`. The implementation separates AI processing in a server file from user interaction in a client component. section 4.1.2
For shared AI and UI state, `createAI` can register server actions and provide state through a React context provider. A structured-data variation registers `generateProductList`; its client handler calls the action, adds returned products to the conversation, and handles generation errors. Streaming React components from actions is a further approach that requires additional AI and UI state management. section 4.2.2 section 4.3.4 section 4.1.3
