Back to roadmaps vercel-ai-sdk Course

Text Completion Workflows with useCompletion

While useChat is optimized for back-and-forth conversational dialogue, the useCompletion hook is designed for single-prompt text generation tasks, such as generating headlines, translating documents, or summarizing long paragraphs.


1. What does useCompletion Manage?

  • completion: A single string state representing the streaming generated response.
  • complete: A function triggers that initiates the completion call with a custom prompt argument.
  • input: Holds the current prompt textarea state.

2. Implementing the Copywriting Editor

Here is a React component that generates marketing copy from user notes:

// app/editor/CopywriterPanel.tsx
"use client";

import { useCompletion } from "ai/react";

export default function CopywriterPanel() {
  const { completion, input, handleInputChange, handleSubmit, isLoading } = useCompletion({
    api: "/api/completion",
  });

  return (
    <div className="max-w-xl mx-auto p-6 bg-white rounded-2xl border shadow mt-8">
      <h2 className="text-lg font-bold mb-4">Marketing Copy Generator</h2>

      {/* Input Form */}
      <form onSubmit={handleSubmit} className="space-y-4">
        <textarea
          value={input}
          onChange={handleInputChange}
          className="w-full border p-3 rounded-lg text-sm focus:outline-none"
          placeholder="Enter product features (e.g. fast database sync, secure webhooks)..."
          rows={4}
        />
        <button type="submit" className="bg-indigo-600 text-white font-semibold px-4 py-2 rounded-lg text-sm transition hover:bg-indigo-700">
          Generate Copy
        </button>
      </form>

      {/* Output Stream */}
      <div className="mt-6">
        <h3 className="text-sm font-semibold text-gray-500">Generated Response:</h3>
        <div className="mt-2 p-4 bg-gray-50 rounded-lg min-h-24 whitespace-pre-wrap text-sm leading-relaxed">
          {completion || (isLoading ? "Typing..." : "No copy generated yet.")}
        </div>
      </div>
    </div>
  );
}

3. Implementing the Backend Route

Add a corresponding API handler to complete the query:

// app/api/completion/route.ts
import { streamText } from "ai";
import { defaultModel } from "../../../lib/models";

export async function POST(req: Request) {
  const { prompt } = await req.json();

  const result = await streamText({
    model: defaultModel,
    prompt: `Write 3 catchy marketing slogans based on these notes: ${prompt}`,
  });

  return result.toDataStreamResponse();
}
Published on Last updated: