The 'use server' directive marks a file or function for server-only execution in a Next.js application. File-level placement applies to every export; function-level placement limits server execution to one async function. This keeps database operations, external API calls, sensitive data, and API keys out of the client bundle. section 4.1.2 section 9.4.2
Use the directive to structure server-side application work:
- Place 'use server' at the top of a file when every exported function belongs on the server. section 4.1.2
- Place 'use server' inside an async function when only that function should become a server action. section 4.1.2
- Keep provider calls, database access, streaming logic, and private environment variables behind the server boundary. section 4.1.2 section 9.4.2
- Call server actions directly from components instead of retaining an API route handler for the same operation. section 4.1.2
Streaming a conversation from a server action
'use server'; import { streamText } from 'ai'; import { createStreamableValue } from 'ai/rsc'; export async function continueConversation(history, provider, model) { 'use server'; const supportedModel = getSupportedModel(provider, model); const stream = createStreamableValue(); const { textStream } = await streamText({ model: supportedModel, messages: history }); for await (const text of textStream) stream.update(text); stream.done(); return { messages: history, newMessage: stream.value }; } section 4.1.2
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,
};
}
Trace how user input reaches the AI provider and how streamed response chunks return to the client while conversation state remains available. section 4.1.2
