Translation
Two APIs that belong together: LanguageDetector works out what language a piece of text is in, and Translator turns it into another - both on the device.
@inject Bit.Butil.Translator translator, LanguageDetector languageDetectorMDN reference
en → fr may not be able to do fr → ja. Probe the pair you
actually need. Chromium only; see LanguageModel for the rest.
Ranks the candidate languages, most confident first. A result of 'und' is the detector saying it could not decide - short input often lands there. This is the natural front half of translation.
@inject Bit.Butil.LanguageDetector languageDetector
await using var detector = await languageDetector.Create();
var candidates = await detector.Detect(text);
var best = candidates.FirstOrDefault()?.DetectedLanguage;Availability takes the pair, either as a TranslatorOptions or as two BCP 47 tags. Downloadable means creating a session will fetch that pair's model first.
var availability = await translator.Availability("en", "fr");
if (availability == AiAvailability.Downloadable)
{
// creating the session will download - do it from a user gesture, show progress
}Create a session for the pair, then translate through it as many times as you like. TranslateStreaming reports the translation as it is produced, which is worth it for anything longer than a sentence. Dispose the session when the pair is no longer needed.
await using var session = await translator.Create("en", "fr",
onDownloadProgress: p => { _progress = p; InvokeAsync(StateHasChanged); });
var translated = await session!.Translate(text);The two together are what 'translate this page for me' actually is: detect the source, create a translator into the user's own language, and skip the whole thing when they already match.
await using var detector = await languageDetector.Create();
var detected = (await detector.Detect(text)).FirstOrDefault()?.DetectedLanguage;
if (detected is null or "und" || detected == userLanguage) return text;
await using var session = await translator.Create(detected, userLanguage);
return await session!.Translate(text) ?? text;API reference
ValueTask<bool> IsSupported()ValueTask<AiAvailability> Availability(TranslatorOptions options) / Availability(string sourceLanguage, string targetLanguage)ValueTask<TranslatorSession?> Create(TranslatorOptions options, Action<double>? onDownloadProgress = null) / Create(string sourceLanguage, string targetLanguage, …)ValueTask<string?> Translate(string input)Task<string> TranslateStreaming(string input, Action<string>? onChunk = null)ValueTask DisposeAsync()ValueTask<bool> IsSupported()ValueTask<AiAvailability> Availability() / Availability(LanguageDetectorOptions options)ValueTask<LanguageDetectorSession?> Create(LanguageDetectorOptions? options = null, Action<double>? onDownloadProgress = null)ValueTask<LanguageDetectionResult[]> Detect(string input)ValueTask DisposeAsync()