Skip to content
SoyGarfield
Research #07

Come ho rilevato la lingua per paese senza selettore manuale: il caso iFace Simulator

Conviene rilevare la lingua del visitatore tramite geolocalizzazione IP, o un selettore di lingua manuale è sempre più affidabile?

Di Pietro Fiorillo ·

Indice dell'articolo
Diagramma di un flusso lineare. Il visitatore arriva senza lingua nell'URL, la sua IP viene geolocalizzata con ipapi.co, confrontata con un elenco di paesi ispanofoni e lusofoni scritto a mano, reindirizzato a es, en o pt, e infine viene caricata in modo differito la rotta del simulatore.
Da una visita senza lingua a una rotta caricata in modo differito nella lingua corretta, senza che il visitatore scelga nulla. Diagramma originale.

Il problema: spiegare modelli di formazione medico-estetica a mercati diversi

iFace produce modelli di formazione fisici e digitali perché i medici possano esercitarsi su procedure estetiche prima di operare. Aveva bisogno di un sito che spiegasse ogni simulatore con chiarezza e funzionasse in più lingue in base al paese del visitatore, senza obbligarlo a scegliere la lingua a mano.

Come si costruisce ogni simulatore: rotte a caricamento differito, senza un registro centrale

Non c'è un array di configurazione che elenca i simulatori disponibili. Ognuno è, letteralmente, una riga di import() differito più una riga di <Route> nel router.

const R1   = lazy(() => import('./components/R1/R1'));
const Lips = lazy(() => import('./components/Lips/Lips'));
const INose = lazy(() => import('./components/INose/INose'));

<Route path="simulators/r1" element={<R1 />} />
<Route path="simulators/lips" element={<Lips />} />
<Route path="simulators/inose" element={<INose />} />
{/* Models */}
<Route path="models/discovery-model" element={<DiscoveryModel />} />
Codice reale (abbreviato) di src/App.jsx.

Aggiungere un nuovo simulatore significa aggiungere queste due righe, non modificare un sistema di moduli. È un'architettura semplice finché il numero di simulatori non cresce molto, momento in cui un registro dati varrebbe probabilmente la pena.

Come il sito decide in quale lingua mostrarti il contenuto

Il sito usa i18next con tre pacchetti di traduzione completi: inglese, spagnolo e portoghese. Non c'è italiano, nonostante io lo parli: il prodotto punta specificamente a mercati anglofono, ispanofono e lusofono.

import en from './locales/en/translation.json';
import es from './locales/es/translation.json';
import pt from './locales/pt/translation.json';

const resources = { en: { translation: en }, es: { translation: es }, pt: { translation: pt } };

i18n.use(initReactI18next).init({
  resources,
  lng: 'en',
  fallbackLng: 'en',
});
Codice reale (abbreviato) di src/i18n.js.

La decisione su quale lingua mostrare non dipende da un selettore che il visitatore sceglie: un componente geolocalizza l'IP con ipapi.co e la confronta con elenchi di paesi ispanofoni e lusofoni scritti direttamente nel codice. Se il paese coincide, reindirizza a /es o /pt; altrimenti resta su /en.

Non è una piattaforma di simulatori spaziali: è un negozio con un carrello semplice

Ogni prodotto ha un oggetto carrello semplice, con id, nome e prezzo.

{
  cartId: 'r1-simulator',
  cartName: 'R1 Simulator',
  price: 344,
}
Codice reale (abbreviato) di R1Simulator.jsx.

Come ho validato questa architettura

Ho eseguito npm run build contro il repository reale (Vite 7, React 19) e ho misurato il risultato invece di descriverlo a memoria.

Metriche reali misurate il 18 ottobre 2026.
MetricaRisultatoAmbiente / evidenza
Lighthouse Performance (mobile, lab)69 / 100Lighthouse 13.5.0, throttling simulato
LCP (lab)5,0 sStessa misurazione Lighthouse, non è un dato di campo (CrUX)
Tempo di build locale3,39 svite build, il più veloce di tutta questa serie
Dimensione dell'export3,7 MB in 129 fileCartella /dist generata da quella build
Lingue supportate3 (en, es, pt)Cartelle reali in src/locales, senza italiano
Commit di sviluppo23, da luglio ad agosto 2026git log del repository

La build stessa ha segnalato un chunk JavaScript di oltre 500 KB (index-BEfQztCT.js, 560 KB non compresso), qualcosa che vale la pena dividere ulteriormente se il sito continua a crescere.

La lingua di un prodotto la decide il suo mercato, non la biografia di chi lo costruisce.

Pietro Fiorillo

Il mio ruolo in questo progetto

Il mio ruolo in iFace Simulator ha incluso lo sviluppo del frontend, l'integrazione di Sanity come CMS e la strategia multilingue, come parte del mio lavoro in MANYA Digital.

Cosa farei diversamente: una descrizione pubblica che non corrispondeva al progetto

Prima di scrivere questo articolo, la pagina di questo progetto sul mio sito descriveva una «piattaforma di simulatori spaziali» con una «dashboard di controllo in tempo reale». Rivedendo il repository reale, ho scoperto che si tratta di un sito di marketing ed e-commerce per modelli di formazione medico-estetica, senza dashboard né dati in tempo reale di alcun tipo. Ho già corretto quella descrizione nella pagina del progetto; la documento qui perché è esattamente il tipo di errore che vale la pena ammettere invece di lasciare correre.

Cosa proverei dopo

Verificherei che esista un selettore di lingua manuale visibile per quando la geolocalizzazione sbaglia (per esempio con una VPN), e dividerei il chunk JavaScript di 560 KB segnalato dalla build prima che il sito aggiunga altri simulatori.

Fonti

Domande frequenti

Perché il sito non ha una versione in italiano se tu sei italiano?

Perché il prodotto è pensato specificamente per i mercati anglofono, ispanofono e lusofono, non per coprire tutte le lingue che parlo io. Le decisioni linguistiche di un progetto rispondono al suo mercato, non a chi lo costruisce.

Come decide il sito quale lingua mostrare?

Geolocalizza l'IP del visitatore con ipapi.co e lo confronta con due elenchi di paesi (ispanofoni e lusofoni) scritti a mano nel codice. Se il paese è in uno dei due elenchi, reindirizza a /es o /pt; altrimenti resta su /en di default.

Cosa succede se qualcuno usa una VPN?

Vedrebbe la lingua corrispondente al paese di uscita della VPN, non al suo paese reale. È un limite intrinseco a qualsiasi rilevamento via IP, non specifico di questo progetto, e il selettore di lingua manuale (se presente nell'interfaccia) resta il modo per correggerlo.

C'è una dashboard o dati in tempo reale?

No. Ho controllato il codice cercando websocket, librerie di grafici o hook di polling, e non ne ho trovato nessuno. È un sito di marketing ed e-commerce con rotte a caricamento differito, non una piattaforma di monitoraggio.

Perché Vite e React Router invece di Next.js?

Perché il sito non ha bisogno di rendering lato server né di rotte ibride: è una SPA di marketing con caricamento differito per prodotto, e Vite dà una build più semplice e veloce per questo caso d'uso.

Quanto costa mantenere un sito così?

L'hosting di una SPA statica è minimo. Il contenuto si modifica da Sanity senza toccare codice, quindi il costo reale è il tempo di mantenere sincronizzate le traduzioni nelle tre lingue.