Skip to content

useSummarizer

React adapter for @web-ai-sdk/summarizer. Auto-runs on mount, re-runs when input / language / config options change, and streams chunks through state updates. For the conceptual overview see Summarizer.

Before shipping, review the Production checklist for task-relevant text extraction, safe streaming, progress, and cache freshness.

To warm the session before the hook first runs, call prepareSummarizer from the core package on user intent. See the Session lifecycle guide.

Click “Summarize the article” to run the model on the article below; nothing runs on page load. The summary streams in as the model produces it. Click Stop to cancel. Results are cached for ten minutes; use “Fresh run” to regenerate.

import { useSummarizer } from "@web-ai-sdk/summarizer/react";
export function Summary({ text }: { text: string }) {
const { status, output } = useSummarizer({
input: text,
language: "en",
type: "key-points",
length: "short",
});
if (status === "unavailable") return null;
return <aside>{output}</aside>;
}

The hook auto-runs whenever its meaningful inputs change. Empty / whitespace-only input keeps the hook in "idle" without invoking the model.

idle ───► loading ───► streaming ───► done
unavailable ◄─── (no API) │
dismiss()
  • idle: hook mounted, waiting for input to be non-empty.
  • loading: warming the Summarizer.create() session (~1-3s cold start).
  • streaming: chunks arriving. result.output grows as they land; render it directly for a typewriter effect.
  • done: final summary in result.output. result.fromCache is true if the response came from the opt-in result cache.
  • unavailable: API missing. Render nothing.

The hook exposes the same two caches as the vanilla summarize():

  • Session cache (in-memory, always on): warm sessions are reused across calls with the same { language, type, length, sharedContext, … } shape. Plan your inputs around these dimensions to keep cold-starts rare.
  • Result cache (opt-in): off by default. Pass cache: "session" for per-tab caching, cache: "local" to persist across tabs, or any { get, set }-shaped object for a custom backend.

Built-in "session" / "local" entries expire after one hour by default. Pass cacheTtl (milliseconds) to change the TTL per call. Pass cacheRefresh: true to skip the read and replace the cached value after a successful run. Custom { get, set } caches own their expiry policy.

result.fromCache lets you render a “From cache” hint or skip a re-fetch loop entirely.

result.output updates on every chunk during streaming. A naive <p>{result.output}</p> already produces a typewriter effect because React re-renders on each state change. If chunks arrive faster than you want to repaint, debounce on the consumer side.

import type { UseSummarizerOptions, UseSummarizerReturn, SummarizerStatus } from "@web-ai-sdk/summarizer/react";
type SummarizerStatus = "idle" | "loading" | "streaming" | "done" | "unavailable";
interface UseSummarizerOptions extends Omit<SummarizeOptions, "onUpdate" | "signal"> {
enabled?: boolean; // default: true
// Inherited from SummarizeOptions:
input: string;
language: string;
supportedLanguages?: readonly string[];
type?: "tldr" | "key-points" | "teaser" | "headline";
length?: "short" | "medium" | "long";
format?: "plain-text" | "markdown";
preference?: "auto" | "speed" | "capability";
sharedContext?: string;
monitor?: (m: CreateMonitor) => void;
cache?: "session" | "local" | { get, set };
cacheKey?: string;
cacheTtl?: number; // built-in shortcut TTL in ms; default 1 hour
cacheRefresh?: boolean; // skip the cache read, write the fresh result
}
interface UseSummarizerReturn {
status: SummarizerStatus;
output: string | null;
error: Error | null;
fromCache: boolean;
dismiss(): void; // sets status to "unavailable", clears output
}
declare const useSummarizer: (options: UseSummarizerOptions) => UseSummarizerReturn;

Source: packages/summarizer/src/react/index.ts.