Skip to content

Proofreader API

This package wraps the built-in Proofreader API. It returns corrected text and individual corrections with source offsets. It also adds session reuse and optional result caching. For React, see useProofreader.

Before shipping, review the Production checklist for preserving originals, Accept/Reject/Undo flows, safe rendering, and cache freshness.

Use prepareProofreader to warm a session on user intent and release it when the feature closes. See the Session lifecycle guide.

import { proofread } from "@web-ai-sdk/proofreader";
const result = await proofread({
input: "I seen him yesterday at the store, and he bought two loafs of bread.",
expectedInputLanguages: ["en"],
});
console.log(result.output?.correctedInput);
for (const c of result.output?.corrections ?? []) {
console.log({
startIndex: c.startIndex,
endIndex: c.endIndex,
correction: c.correction,
});
}

result.output is null when the input is empty; otherwise correctedInput is the corrected text and corrections is the list of per-issue edits.

interface ProofreadOptions {
input: string;
expectedInputLanguages?: readonly 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
signal?: AbortSignal;
}
Name Type Description
input required string Text to proofread. Empty / whitespace resolves to { output: null }.
expectedInputLanguages readonly string[] BCP-47 languages the proofreader should expect as input. English-only today; see Language support.
monitor (m) => void Observe the first-call model download.
cache "session" | "local" | { get, set } Opt-in result cache (stores the serialized output).
cacheKey string Override the default cache key.
cacheTtl number TTL in milliseconds for entries written by the built-in "session" / "local" shortcuts. Defaults to one hour. Ignored by custom { get, set } caches.
cacheRefresh boolean Skip the cache read and replace the cached value after a successful run. The refreshed run reports cached: false.
signal AbortSignal Abort signal.
interface ProofreadCorrection {
startIndex: number; // inclusive offset into the original input
endIndex: number; // exclusive offset into the original input
correction: string; // suggested replacement
type?: string; // optional platform metadata
explanation?: string; // optional platform metadata
}
interface ProofreadOutput {
correctedInput: string;
corrections: ProofreadCorrection[];
}
interface ProofreadResult {
output: ProofreadOutput | null;
cached: boolean;
}

The corrections offsets index into the original input, so you can highlight each error by slicing between offsets:

let cursor = 0;
const spans: Array<{ text: string; error: boolean }> = [];
for (const c of output.corrections) {
if (c.startIndex > cursor)
spans.push({ text: input.slice(cursor, c.startIndex), error: false });
spans.push({ text: input.slice(c.startIndex, c.endIndex), error: true });
cursor = c.endIndex;
}
if (cursor < input.length)
spans.push({ text: input.slice(cursor), error: false });

The Proofreader API is English-only today. expectedInputLanguages accepts an array for forward compatibility, but requesting a language the browser can’t proofread causes the native create() to reject, which this wrapper surfaces as ProofreaderUnavailableError. Pass ["en"] or omit the option until more languages ship.

Unlike the Writer and Rewriter, the Proofreader has no streaming surface; proofread() resolves once with the full result.

The vanilla proofread() throws ProofreaderUnavailableError when the API is missing:

import { proofread, ProofreaderUnavailableError } from "@web-ai-sdk/proofreader";
try {
const result = await proofread({ input: text });
} catch (err) {
if (err instanceof ProofreaderUnavailableError) return;
throw err;
}

AbortSignal is supported.