useDetector
React adapter for @web-ai-sdk/detector. Auto-detects the language of text on mount and re-runs whenever the text changes. For the conceptual overview see Detector.
Live demo
Edit the input; the badge updates as you type. The list under the badge shows the top candidates with their confidences.
Usage
import { useDetector } from "@web-ai-sdk/detector/react";
export function LangBadge({ text }: { text: string }) { const { status, language, confidence } = useDetector({ text });
if (status !== "done" || !language) return null; return ( <span> {language} · {Math.round(confidence * 100)}% </span> );}The hook auto-runs whenever text changes. Empty / whitespace-only inputs keep the hook in "pending" without invoking the model. The hook is the right choice when you want a passive badge that mirrors live input.
State machine
pending ───► loading ───► done │unavailable ◄── (no flag / │ no model) │ ▼ text empty ─► pendingpending: hook mounted, input empty or whitespace-only.loading: input present, detection in flight (~100-300ms cold, sub-50ms warm).done: detection complete.languageis the top BCP-47 code (ornullif belowminConfidence).confidenceis the top score.allis the full sorted list.unavailable: API missing. Render nothing or a fallback.
Confidence threshold
const { language, confidence } = useDetector({ text, minConfidence: 0.8,});
// Below 0.8 confidence, `language` is null and you can render nothing.Bias hints
const result = useDetector({ text, expectedInputLanguages: ["pt", "es", "en"],});Use this when you have a prior on what the input language might be; it helps the model break ties between similar languages.
Caching
The result cache is opt-in:
import { createSessionStorageCache } from "@web-ai-sdk/detector";
const cache = useMemo(() => createSessionStorageCache(), []);
const result = useDetector({ text, cache });result.fromCache is true when the cache served the result. Memoize the cache (or any { get, set }-shaped object) so React doesn’t restart on every render.
Aborting
The hook aborts any in-flight call when text changes or the component unmounts. You don’t need to manage AbortController directly.
Reference
import type { UseDetectorOptions, UseDetectorReturn, DetectorStatus } from "@web-ai-sdk/detector/react";
type DetectorStatus = "pending" | "loading" | "done" | "unavailable";
interface UseDetectorOptions extends Omit<DetectOptions, "text" | "signal"> { text: string; // empty / whitespace-only keeps the hook in "pending" enabled?: boolean; // default: true // Inherited from DetectOptions: expectedInputLanguages?: readonly string[]; minConfidence?: number; createOptions?: LanguageDetectorCreateOptions; cache?: DetectionCache; cacheKey?: string;}
interface UseDetectorReturn { status: DetectorStatus; language: string | null; // top BCP-47 candidate; null below minConfidence confidence: number; // confidence of the top result all: DetectionResult[]; // full sorted list of candidates error: Error | null; fromCache: boolean; // true when served by the opt-in cache}
declare const useDetector: (options: UseDetectorOptions) => UseDetectorReturn;Source: packages/detector/src/react/index.ts.