Il browser ora può tradurre la tua app. Ecco cosa non può fare.
A giugno 2026 la domanda «mi serve davvero ancora uno strumento di traduzione?» ha acquisito un nuovo taglio. Il 2 giugno, Microsoft ha annunciato che Microsoft Edge 148 integra una Translator API, basata su modelli sul dispositivo che coprono più di 145 lingue, gratuita e privata. Chrome di Google ha la stessa API stabile da Chrome 138 (giugno 2025), oggi per 37 lingue e varianti. Due dei browser più usati al mondo ora possono tradurre qualsiasi pagina, localmente, gratis.
Vale dunque la pena chiedersi onestamente: se il browser traduce la tua app gratis, ti serve ancora un sistema di gestione delle traduzioni?
La risposta breve: il browser traduce, il TMS governa. Non si contendono lo stesso lavoro. Questo articolo è la versione onesta del perché, con una ricetta eseguibile che mette il browser al lavoro come fallback sancito mentre le tue traduzioni restano governate.
- Chrome: Translator API e Language Detector API stabili da Chrome 138 (giugno 2025), 37 lingue e varianti, solo desktop
- Edge: Translator API disponibile da Edge 148 (annunciata il 2 giugno 2026), sul dispositivo, 145+ lingue
- Come funziona: un modello dedicato viene scaricato al primo utilizzo, poi gira localmente. Gratuito, utilizzabile offline, niente lascia il dispositivo
- Non ancora uno standard: solo i due browser Chromium la integrano. Mozilla ha depositato una posizione negativa; WebKit nessuna
- Cosa è: un miglioramento al momento della visualizzazione per testo renderizzato. Cosa non è: chiavi, stato di revisione, terminologia, punteggio di qualità, SSR, SEO o copertura mobile
Cosa fa davvero il browser, e fa bene
Va dato a Cesare quel che è di Cesare. La Translator API integrata è un pezzo di ingegneria di piattaforma davvero bello, e la dimostrazione è breve. Rileva la funzionalità, verifica che la coppia di lingue sia disponibile, crea un traduttore, traduci:
// Miglioramento progressivo: gira solo dove l'API esiste.
if ('Translator' in self) {
const pair = { sourceLanguage: 'en', targetLanguage: 'it' }
const availability = await Translator.availability(pair)
// 'unavailable' | 'downloadable' | 'downloading' | 'available'
if (availability !== 'unavailable') {
const translator = await Translator.create({
...pair,
monitor (m) {
m.addEventListener('downloadprogress', (e) => {
console.log(`Download del modello: ${Math.round(e.loaded * 100)}%`)
})
}
})
const out = await translator.translate('Where is the nearest bus stop?')
console.log(out) // "Dov'è la fermata dell'autobus più vicina?"
translator.destroy() // libera il modello quando hai finito
}
}È tutto qui. Il modello di una coppia di lingue si scarica una volta, poi resta disponibile da un sito all'altro, e l'API funziona allo stesso modo in Edge (documentata qui), inclusa una variante translateStreaming() per l'output token per token. Quello che ottieni è reale:
- Istantaneo. Dopo il download una tantum del modello, la traduzione avviene localmente senza round-trip di rete.
- Gratuito. Niente chiavi API, niente fatturazione a carattere, niente quota.
- Privato. Il testo non lascia mai il dispositivo e non viene raccolto per addestrare modelli.
- Offline. Una volta scaricato il modello, funziona senza connessione.
Per «una visitatrice arriva su una pagina in una lingua che non hai mai pubblicato e vuole comunque leggerla», è eccellente. È la versione moderna, sul dispositivo, della barra di traduzione, accessibile al tuo codice. Se questo è il tuo bisogno, usala e smetti di leggere qui.
Ma è un bisogno diverso dal gestire un prodotto localizzato. Ecco dove passa la linea.
Il divario di governance
Un sistema di gestione delle traduzioni non si occupa di trasformare una stringa in un'altra. Si occupa di fare della traduzione un processo controllato, verificabile e consegnabile, attraverso un team e nel tempo. L'API del browser non fa nulla di tutto ciò, per progettazione, e vale la pena essere concreti anziché sprezzanti su cosa manca esattamente.
Niente chiavi, niente struttura. L'API traduce una stringa che le passi. Non ha idea che questa stringa sia checkout.pay_now, che viva nel namespace checkout, che abbia una variante al plurale o che abbia già una traduzione francese approvata che ti è costata denaro. Traduce testo, non il tuo modello di contenuto. Tutto ciò che sta a valle di «abbiamo un catalogo strutturato di chiavi» qui semplicemente non esiste.
Niente stato di revisione, niente prova di approvazione. Non esiste alcuna traccia che un essere umano abbia guardato la traduzione italiana della tua politica di rimborso e l'abbia approvata. Questa traccia sempre più non è opzionale: ai sensi del regolamento UE sull'IA, il percorso che mantiene un contenuto di interesse pubblico tradotto automaticamente fuori dall'obbligo di divulgazione visibile passa per una revisione umana documentata, e una traduzione prodotta al volo nel browser della visitatrice non ha, per definizione, alcuna revisione associata (abbiamo trattato questo obbligo e l'esenzione del flusso di revisione separatamente). La verifica di conformità non può avvenire lato client a posteriori.
Niente controllo di terminologia o voce del brand. Il tuo prodotto lo chiama «spazio di lavoro», non «ufficio», e il tuo tono è il «tu» informale, non il «Lei» formale. Il modello del browser non conosce il tuo glossario né la tua guida di stile, e non c'è modo di comunicarglieli: la Translator API è un modello di traduzione sigillato e specifico per il compito, non un LLM istruibile, quindi non ha alcun canale di prompt o istruzione di sistema attraverso cui iniettare terminologia, tono o memoria di traduzione. Ogni visitatrice può ottenere una resa leggermente diversa, fuori brand, dello stesso pulsante.
Niente Quality Estimation. Quando il modello sbaglia una traduzione, niente la segnala. Non c'è punteggio di confidenza, nessun instradamento dei casi dubbi verso un essere umano. La Quality Estimation e un flusso di revisione sono esattamente la rete di sicurezza che la traduzione sul dispositivo rimuove.
Niente fedeltà di formato. Plurali, forme di genere, interpolazione ({{count}} items, {{name}}), componenti annidati dentro una frase: questi sono problemi di i18n, non problemi di traduzione di frasi. Passa a un modello una stringa con un segnaposto e stai scommettendo che il segnaposto sopravviva al posto giusto. Le regole di plurale ICU non sono qualcosa su cui una chiamata di traduzione al momento della visualizzazione ragiona.
Niente SSR, niente SEO. Questo è il punto grosso per un sito pubblico. Il browser traduce il DOM dopo che è stato renderizzato, nel browser della visitatrice. I crawler dei motori di ricerca, le anteprime dei link e il tuo rendering lato server vedono solo la lingua originale. Una pagina tradotta dal browser è, per Google, una pagina non tradotta. Non puoi posizionarti in un mercato la cui lingua esiste solo lato client.
Lacune di copertura mobile. Le API Translator e Language Detector di Chrome sono documentate come solo desktop; sui dispositivi mobili non funzionano. Una larga parte dei tuoi utenti è su telefono, dove tutto questo meccanismo è attualmente assente.
Non uno standard consolidato. Solo i due browser Chromium la integrano. Mozilla ha registrato una posizione negativa sulla Web Translation API e persegue una controproposta, e WebKit non ha preso alcuna posizione. L'API è in incubazione nel W3C Web Machine Learning Working Group, il che significa che la sua forma può ancora cambiare. Costruirci sopra un'esperienza centrale oggi significa costruire sull'anteprima di un'unica famiglia di motori, non sulla piattaforma web.
Niente di tutto ciò rende cattiva l'API del browser. La rende una tecnologia di visualizzazione. L'errore sarebbe trattare una tecnologia di visualizzazione come una tecnologia di gestione dei contenuti.
L'architettura: il browser traduce, il TMS governa
Metti entrambi dove devono stare e smettono di farsi concorrenza:
-
Il nucleo governato. Le tue traduzioni vere vivono in un TMS: strutturate per chiave e namespace, tradotte da IA e traduzione automatica con il tuo glossario e la tua guida di stile come contesto, valutate dalla Quality Estimation, revisionate da esseri umani dove conta, versionate e consegnate a ogni browser, ogni crawler e ogni telefono tramite CDN. È il contenuto di cui rispondi, quello che si posiziona, quello che un revisore può ricostruire.
-
Il fallback sancito. Per i divari, le lingue che non hai ancora pubblicato, la chiave nuova di zecca andata online un'ora fa, la lingua di coda lunga che non presidierai mai, lascia che intervenga il browser. All'istante, gratis, per i visitatori il cui browser può. È un degrado elegante, non il prodotto.
Il trucco è collegarli in modo che il fallback sia temporaneo e auto-riparante: ogni volta che il browser deve tradurre qualcosa, quel fatto diventa un segnale che rifluisce nel nucleo governato e lo fa tradurre come si deve per la volta successiva.
La ricetta: fallback su chiave mancante di i18next, auto-riparante verso Locize
Ecco quel ciclo, concretamente, con i18next e Locize. L'idea:
- Una chiave non ha traduzione nella lingua attiva. i18next mostra il testo sorgente (il suo fallback normale) e attiva
saveMissing. saveMissingsegnala la chiave a Locize, dove traduzione automatica e Quality Estimation si mettono al lavoro e un essere umano può revisionare.- Nel frattempo, per i visitatori su un browser compatibile, la Translator API sul dispositivo traduce il testo di fallback sul posto, così vedono subito la loro lingua invece dell'inglese.
- Alla pubblicazione successiva, la traduzione in piena regola, revisionata, è in Locize e sul CDN. La chiave ora esiste nella lingua di destinazione, il fallback non si attiva più, e la traduzione governata ha silenziosamente sostituito l'ipotesi fatta sul dispositivo.
Prima il lato i18next. Il backend Locize segnala le chiavi mancanti per te:
import i18next from 'i18next'
import { initReactI18next } from 'react-i18next'
import Backend from 'i18next-locize-backend'
i18next
.use(Backend)
.use(initReactI18next)
.init({
fallbackLng: 'en',
saveMissing: true, // segnala a Locize le chiavi mancanti nella lingua attiva
backend: {
projectId: '<your-project-id>',
version: 'latest',
// Una chiave API di scrittura serve SOLO per SEGNALARE le chiavi mancanti.
// Non consegnarla mai agli utenti finali. Vedi le avvertenze sotto:
// segnala in dev/staging o dietro il tuo endpoint, non nel bundle client
// di produzione.
apiKey: import.meta.env.DEV ? '<dev-only-api-key>' : undefined
}
})Ora il fallback al momento della visualizzazione. Un piccolo hook legge una chiave; se i18next ha dovuto ripiegare su un'altra lingua, chiede al browser di tradurre il testo di fallback sul dispositivo, e lo sostituisce non appena è pronto:
import { useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
// Colma una traduzione mancante sul dispositivo, gratis, mentre Locize fa
// tradurre la chiave per davvero. Puro miglioramento progressivo: dove la
// Translator API è assente (mobile, Firefox, Safari), questo restituisce
// semplicemente il testo di fallback.
export function useGovernedT (key) {
const { t, i18n } = useTranslation()
// returnDetails ci dice quale lingua i18next ha effettivamente usato.
const details = t(key, { returnDetails: true })
const target = i18n.language
const source = details.usedLng // la lingua su cui ha ripiegato
const fallbackText = details.res // testo in quella lingua di fallback
const missingInTarget = !!source && source !== target
const [onDevice, setOnDevice] = useState(null)
useEffect(() => {
setOnDevice(null)
if (!missingInTarget) return
if (typeof self === 'undefined' || !('Translator' in self)) return
let cancelled = false
;(async () => {
const pair = { sourceLanguage: source, targetLanguage: target }
const availability = await Translator.availability(pair)
if (availability === 'unavailable') return
const translator = await Translator.create(pair)
const translated = await translator.translate(fallbackText)
translator.destroy()
if (!cancelled) setOnDevice(translated)
})().catch(() => { /* in caso di errore resta sul testo di fallback */ })
return () => { cancelled = true }
}, [key, source, target, fallbackText, missingInTarget])
// Mostra la traduzione sul dispositivo quando è pronta, fino ad allora il testo di fallback.
return missingInTarget && onDevice ? onDevice : fallbackText
}E in un componente, si legge come qualsiasi altra traduzione:
function CheckoutButton () {
const label = useGovernedT('checkout.pay_now')
return <button className='btn-primary'>{label}</button>
}Un checkout.pay_now nuovo di zecca che esiste solo in inglese farà: mostrare «Pay now» istantaneamente a tutti, mostrare «Paga ora» un attimo dopo a una visitatrice su Chrome o Edge desktop, e segnalarsi a Locize così che entro un ciclo di pubblicazione ogni visitatrice, su ogni browser, ogni telefono e ogni crawler, ottenga una traduzione italiana revisionata e valutata in qualità dal CDN. Il fallback si ripara da solo.
Avvertenze oneste
- Solo Chrome 138+ ed Edge 148+ desktop. Tutti gli altri (Firefox, Safari, ogni telefono) ottengono il testo di fallback, il che va bene, è proprio il senso del miglioramento progressivo. Non far dipendere nulla di importante dall'attivazione del percorso sul dispositivo.
- Tieni la chiave di scrittura fuori dal client. Segnalare le chiavi mancanti richiede una credenziale di scrittura. Esegui
saveMissingin sviluppo o staging, oppure fallo passare per il tuo endpoint, anziché consegnare una chiave API in un bundle di produzione. La traduzione sul dispositivo in sé non richiede alcuna chiave ed è sicura da consegnare. - È un ripiego, non la traduzione. L'output sul dispositivo non è revisionato, non valutato e fuori glossario. Ti regala una migliore prima impressione mentre la traduzione governata viene prodotta. Non trattarlo mai come definitivo.
- Il primo utilizzo scarica un modello. La primissima traduzione di una coppia di lingue attiva un download una tantum del modello, così la prima visitatrice di una sessione vede il testo di fallback per un istante in più. Il callback
monitorti permette di mostrare l'avanzamento se vuoi.
Una nota lungimirante, e solo una nota: proprio questo cablaggio da chiave mancante a fallback è la giuntura naturale dove le funzionalità di traduzione su richiesta tendono a crescere, quindi è un pattern utile da avere pronto, indipendentemente da dove andranno le API del browser. Nessuna promessa, solo un buon punto d'appoggio.
Dove entra in gioco Locize
Il browser è un buon traduttore. Non è un posto dove gestire traduzioni, e non ha mai cercato di esserlo. Locize è il nucleo governato in cui il fallback si ripara: chiavi e namespace strutturati, traduzione IA automatica con il tuo glossario e la tua guida di stile, Quality Estimation su ogni traduzione IA, un flusso di revisione e una cronologia completa per le traduzioni di cui rispondi, e consegna via CDN così che il risultato raggiunga ogni browser, ogni telefono e ogni crawler, non solo i visitatori che per caso sono su Chromium desktop.
Usa il browser per ciò in cui è davvero bravo, traduzione istantanea, gratuita e privata al momento della visualizzazione, e tieni la governance dove deve stare.
Se vuoi il nucleo governato sotto quel fallback: crea un account Locize gratuito, attiva traduzione automatica e Quality Estimation, e collega saveMissing per segnalare le tue chiavi mancanti. Il browser traduce. Il tuo TMS governa.
Stanco di gestire le traduzioni a mano?
Locize è il backend di gestione delle traduzioni creato dal team di i18next: distribuzione via CDN, traduzione con AI, editing in-context, senza nuovi deploy.
Inizia la prova gratuita di 14 giorni