Skip to content

Language Detector API

Building block for the Web’s Built-in Language Detector API. Detect the language of any text on-device, with confidence scores and a sorted list of alternates. Session reuse, opt-in result caching, AbortSignal-driven cleanup. See useDetector for React.

import { detect } from "@web-ai-sdk/detector";
const result = await detect({ input: "Olá, mundo" });
console.log(result.output?.language); // → "pt"
console.log(result.output?.confidence); // → 0.98
console.log(result.output?.all); // → [{ detectedLanguage, confidence }, ...]

result.output is the detection result with language (BCP-47), confidence, and all (full sorted candidates), or null for empty input or when the top confidence is below minConfidence. result.cached indicates whether the response came from the cache without invoking the model.

interface DetectOptions {
input: string;
expectedInputLanguages?: readonly string[];
minConfidence?: number;
monitor?: (m: CreateMonitor) => void;
cache?: "session" | "local" | { get, set };
cacheKey?: string;
signal?: AbortSignal;
}
NameTypeDescription
input requiredstringText to detect. Empty / whitespace resolves to { output: null }.
expectedInputLanguagesreadonly string[]BCP-47 languages the detector should bias toward (breaks ties between similar pairs).
minConfidencenumberSuppress the result when the top confidence is below this. output becomes null. Defaults to 0.
monitor(m) => voidObserve the first-call model download.
cache"session" | "local" | { get, set }Opt-in result cache. "session" / "local" wrap the matching web-storage; pass an object for a custom backend.
cacheKeystringOverride the default cache key (JSON array string of [input, sortedExpectedInputLanguages]).
signalAbortSignalAbort signal.
interface DetectResult {
output: { language: string; confidence: number; all: DetectionResult[] } | null;
cached: boolean;
}

Chrome’s LanguageDetector exposes LanguageDetector.create({...}) to spin up a session and detector.detect(text) to run it. The wrapper does the same three things on top that the other packages do:

  • Feature detection. isAvailable() / checkAvailability() return false / null on browsers without the API. The vanilla detect() throws DetectorUnavailableError; the React hook surfaces status: "unavailable".
  • Session reuse. Internally caches LanguageDetector.create() by expectedInputLanguages shape. Cold-start is fast on this model (~100-300ms); warm calls are sub-50ms.
  • Optional result cache. Off by default. Pass cache: "session" to memoize results in sessionStorage, or cache: "local" for localStorage, or any { get, set }-shaped object for a custom backend.

By default, detect() returns the highest-confidence candidate regardless of how confident the model actually is. For ambiguous input (single word, emoji-only, gibberish) the model may return detectedLanguage: "und" with low confidence. Set minConfidence to suppress these:

const result = await detect({ input: "??", minConfidence: 0.8 });
// → { output: null, cached: false }

When output is null due to threshold, the full candidate list isn’t returned. Lower minConfidence to 0 and inspect result.output.all if you need to see the alternates.

Pass expectedInputLanguages when you have a prior on what to expect. The model uses it to break ties between similar languages (e.g. pt vs gl, no vs nb):

detect({
input: "Lorem ipsum dolor sit amet",
expectedInputLanguages: ["la", "en", "it"],
});

The hint is also forwarded to availability() so engines that warn on shape mismatch (Edge) stay quiet.

The detector intentionally doesn’t reach into the other packages; one package wraps one capability. To skip the manual language: "en" argument when the input language isn’t known ahead of time, wire the two yourself:

import { detect } from "@web-ai-sdk/detector";
import { summarize } from "@web-ai-sdk/summarizer";
const { output } = await detect({ input: articleText });
await summarize({
language: output?.language ?? "en",
input: articleText,
});

A first-class language: "auto" shortcut isn’t planned for this package. Multi-package compositions like detect-then-summarize, detect-then-translate, or detect-then-prompt are written in consumer code.

AbortSignal is supported. The result cache is not written for aborted runs.

const controller = new AbortController();
detect({ input: "long input…", signal: controller.signal });
controller.abort();

The vanilla detect() throws DetectorUnavailableError when the API is missing or reports availability: "unavailable". Callers branch explicitly:

import { detect, DetectorUnavailableError } from "@web-ai-sdk/detector";
try {
const result = await detect({ input });
} catch (err) {
if (err instanceof DetectorUnavailableError) {
return null;
}
throw err;
}