La Confusión
Los desarrolladores escuchan estos términos:
- "Tenemos que globalizar la aplicación"
- "Añadir localización para Europa"
- "¿Está internacionalizado el código base?"
¿Cuál es la diferencia? ¿Es lo mismo?
No. Están relacionadas pero son distintas. Así de sencillo:
| Término, abreviatura, significado, quién lo hace |------|--------------|---------|-------------| | Internacionalización (i18n) Diseña tu aplicación para soportar múltiples idiomas | Localización: traducir contenidos para mercados específicos Globalización G11n Estrategia global Producto + Marketing
Piénselo de esta manera:
- i18n = Construir un coche con dirección modular (izquierda o derecha)
- L10n = Instalar la dirección a la izquierda para el Reino Unido, a la derecha para EE.UU
- G11n = Decidir en qué países vender coches
Desglosemos cada uno de ellos.
Internacionalización (i18n)
Definición: Diseño de arquitectura de software para soportar múltiples idiomas y regiones sin cambios en el código.
Esto es lo que hacen los desarrolladores antes de traducir nada.
Qué incluye i18n
1. Extraer del código el texto orientado al usuario:
JSX1// ❌ Not internationalized 2<button>Save</button> 3 4// ✅ Internationalized 5<button>{t('save')}</button>
2. Soporta diferentes formatos de datos:
- Fechas: EE.UU. (MM/DD/AAAA) vs Europa (DD/MM/AAAA) vs ISO (AAAA-MM-DD)
- Números: 1.234,56 (US) vs 1.234,56 (Alemania)
- Divisas: 99$ vs 99€ vs ¥100
**3. Direccionalidad del texto
- De izquierda a derecha (LTR): Inglés, español, francés
- De derecha a izquierda (RTL): árabe, hebreo, persa
4. Soporte de pluralización:
- Inglés: 1 artículo, 2 artículos (2 formas)
- Polaco: 1 przedmiot, 2 przedmioty, 5 przedmiotów (3 formas)
- Árabe: 0, 1, 2, 3-10, 11-99, 100+ (¡6 formas!)
5. Permitir expansión de texto:
- El alemán es un 30% más largo que el inglés
- La interfaz de usuario debe permitir: "Save" → "Speichern" (10 caracteres frente a 4)
i18n en la práctica
Ejemplo de reacción:
TSX1import { useTranslation } from 'react-i18next'; 2import { useFormatter } from '@/lib/intl'; 3 4function ProductCard({ product }) { 5 const { t } = useTranslation('common'); 6 const { formatCurrency, formatDate } = useFormatter(); 7 8 return ( 9 <div> 10 <h3>{product.name}</h3> 11 {/* Internationalized string */} 12 <p>{t('product.price_label')}: {formatCurrency(product.price)}</p> 13 14 {/* Internationalized date */} 15 <time>{formatDate(product.releaseDate)}</time> 16 17 {/* Internationalized plural */} 18 <span>{t('product.reviews', { count: product.reviewCount })}</span> 19 </div> 20 ); 21}
Archivos de traducción:
JSON1// en.json 2{ 3 "product": { 4 "price_label": "Price", 5 "reviews": "{{count}} review", 6 "reviews_plural": "{{count}} reviews" 7 } 8} 9 10// de.json 11{ 12 "product": { 13 "price_label": "Preis", 14 "reviews": "{{count}} Bewertung", 15 "reviews_plural": "{{count}} Bewertungen" 16 } 17}
La internacionalización se hace una vez. A continuación, puede agregar idiomas sin tocar el código.
Localización (L10n)
Definición: Adaptar el contenido a una localización específica (idioma + región).
Esto es lo que hacen los traductores. Pero es algo más que traducir.
Qué incluye L10n
1. Traducción (obvio)
- "Guardar" → "Save" (español)
- "Hola" → "你好" (chino)
2. Adaptación cultural
- Colores: Blanco = pureza (Occidente), luto (China)
- Imágenes: Mostrar la piel en mercados conservadores
- Iconos: Pulgar hacia arriba 👍 ofensivo en Oriente Medio
- Ejemplos: Utilizar nombres locales, no "John Smith"
3. Formato regional
- Moneda: $ en EE.UU., € en Europa, £ en el Reino Unido (aunque todas sean inglesas)
- Direcciones: US tiene ZIP, UK tiene código postal
- Números de teléfono: Diferentes formatos a nivel mundial
**4. Cumplimiento jurídico
- GDPR para la UE
- Diferentes políticas de privacidad por región
- Variaciones de las condiciones de servicio
5. Cambios de contenido
- Nombres de los productos: Coca-Cola es 可口可乐 (Kěkǒukělè, "sabrosa diversión") en chino
- Eslóganes adaptados, no traducidos literalmente
- Diferentes características según el mercado (WeChat Pay para China, no para EE. UU.)
L10n Ejemplo: Español para España vs México
Mismo idioma, distinta localización:
| Cadena | España (es-ES) | México (es-MX) |
|---|---|---|
| "Ordenador" | "Ordenador" | "Computadora" |
| "Coche" | "Coche" | "Carro" |
| "You (formal)" | "Usted" | "Tú" (más informal) |
| "Moneda" | "€" (Euro) | "$" (Peso) |
Necesita archivos es-ES.json y es-MX.json separados.
L10n en Código
TSX1// Load locale-specific content 2import { getLocale } from 'next-intl/server'; 3 4async function getLocalizedContent() { 5 const locale = await getLocale(); 6 7 // Different content per locale 8 const pricing = { 9 'en-US': { currency: 'USD', price: 99 }, 10 'en-GB': { currency: 'GBP', price: 79 }, 11 'es-ES': { currency: 'EUR', price: 89 }, 12 'es-MX': { currency: 'MXN', price: 1799 } 13 }; 14 15 return pricing[locale]; 16}
When L10n Goes Wrong
Pepsi en China:
- Eslogan en inglés: "Come alive with Pepsi"
- Traducción al chino: "Pepsi trae a tus ancestros de vuelta de la muerte"
- Fracaso épico.
KFC en China:
- Inglés: "Para chuparse los dedos"
- Chino: "Cómete los dedos"
- También epic fail.
L10n no es sólo traducción; es adaptación cultural.
Globalización (G11n)
Definición: La estrategia empresarial global de globalizarse.
Es lo que hacen los equipos de producto y marketing.
G11n Incluye
1. Estudio de mercado
- ¿A qué países dirigirse?
- ¿Cuál es el TAM (mercado total accesible)?
- ¿Competencia local?
2. Adaptación del producto
- ¿Necesitamos características diferentes para cada región?
- ¿Debemos eliminar las características que no funcionen a nivel local?
3. Estrategia de distribución
- ¿Cómo llegar a los clientes? (tiendas de aplicaciones, web, asociaciones)
- Métodos de pago: Tarjetas de crédito (EE.UU.), Alipay (China), Paytm (India)
- Canales de marketing: Google Ads (mundial), Baidu (China), Yandex (Rusia)
**4. Cumplimiento
- GDPR (UE)
- CCPA (California)
- Requisitos de residencia de datos (Rusia, China)
**5. Operaciones
- Atención al cliente local
- Documentación localizada
- Oficinas regionales
G11n Ejemplo: Uber
Estrategia de globalización de Uber:
- Producto principal: El mismo en todo el mundo (transporte en coche)
- Características localizadas: Pagos en efectivo en India (baja adopción de tarjetas de crédito)
- Precios localizados: Dinámicos, por ciudad
- **Socios localizados: Diferentes conductores por región
- **Marketing localizado: Diferentes campañas por país
No se limitaron a traducir la aplicación, sino que adaptaron su modelo de negocio.
Cómo trabajan juntos
He aquí un flujo del mundo real:
Fase 1: Internacionalizar (Desarrolladores)
Terminal1# Month 1-2 2- Extract all hardcoded strings 3- Use i18n library (react-i18next, next-intl) 4- Support date/number/currency formatting 5- Test with RTL languages 6- Handle text expansion
Output: App está listo para la traducción. Todavía sólo en Inglés, pero diseñado para multi-idioma.
Fase 2: Localizar (Traductores)
Terminal1# Month 3 2- Translate strings to Spanish, French, German 3- Adapt images/icons for cultural fit 4- Localize marketing copy (not literal translation) 5- Legal team adapts Terms of Service
Output: App ahora funciona en 4 idiomas.
Fase 3: Globalizar (Negocio)
Terminal1# Month 4-6 2- Launch in target markets 3- Local marketing campaigns 4- Partner with local payment providers 5- Set up regional customer support 6- Monitor and iterate
Output: Estás vendiendo globalmente.
Glocalización (El Enfoque Moderno)
Glocalización = Globalización + Localización
Piensa globalmente, actúa localmente.
Ejemplos
McDonald's:
- Marca global, núcleo del menú global (Big Mac)
- Adaptaciones locales: McSpicy Paneer (India), Hamburguesa Teriyaki (Japón)
**Netflix
- Plataforma global, biblioteca de contenidos global
- Contenido local: Dramas coreanos, series españolas, películas francesas
- Precios locales: ₹199/mes (India) frente a 15,99 $/mes (EE.UU.)
Airbnb:
- Plataforma global
- Normativa local: Diferentes normas por ciudad
- Métodos de pago locales: Alipay, transferencias bancarias locales
Glocalización en código
TSX1// Feature flags per market 2const features = { 3 'us': { paymentMethods: ['card', 'paypal'], showTipping: true }, 4 'cn': { paymentMethods: ['alipay', 'wechat'], showTipping: false }, 5 'in': { paymentMethods: ['card', 'upi', 'paytm'], showTipping: false } 6}; 7 8function CheckoutPage() { 9 const locale = useLocale(); 10 const marketFeatures = features[locale.split('-')[1].toLowerCase()]; 11 12 return ( 13 <div> 14 {marketFeatures.paymentMethods.map(method => ( 15 <PaymentOption key={method} type={method} /> 16 ))} 17 {marketFeatures.showTipping && <TipSelector />} 18 </div> 19 ); 20}
Implementación Técnica
Vamos a construir una aplicación React correctamente i18n'd, localizada y globalizada.
Paso 1: Internacionalización (Arquitectura del código)
Terminalnpm install react-i18next i18next
TSX1// i18n.ts 2import i18n from 'i18next'; 3import { initReactI18next } from 'react-i18next'; 4 5i18n.use(initReactI18next).init({ 6 resources: { 7 en: { translation: require('./locales/en.json') }, 8 es: { translation: require('./locales/es.json') }, 9 de: { translation: require('./locales/de.json') } 10 }, 11 lng: 'en', 12 fallbackLng: 'en', 13 interpolation: { escapeValue: false } 14}); 15 16export default i18n;
TSX1// Component with proper i18n 2import { useTranslation } from 'react-i18next'; 3 4function HomePage() { 5 const { t, i18n } = useTranslation('common'); 6 7 // Internationalized: supports any language 8 return ( 9 <div dir={i18n.dir()}> {/* RTL support */} 10 <h1>{t('home.title')}</h1> 11 <p>{t('home.subtitle', { name: 'User' })}</p> 12 13 {/* Date formatting */} 14 <time>{new Intl.DateTimeFormat(i18n.language).format(new Date())}</time> 15 16 {/* Number formatting */} 17 <span>{new Intl.NumberFormat(i18n.language).format(1234567)}</span> 18 </div> 19 ); 20}
Paso 2: Localización (Contenido)
Cree contenido específico para la localización:
JSON1// locales/en-US.json 2{ 3 "home": { 4 "title": "Welcome to Our App", 5 "cta": "Get Started Free", 6 "features": { 7 "speed": "Lightning fast", 8 "security": "Bank-level security" 9 } 10 }, 11 "pricing": { 12 "currency": "USD", 13 "monthly": "$99/month" 14 } 15}
JSON1// locales/en-GB.json 2{ 3 "home": { 4 "title": "Welcome to Our App", 5 "cta": "Get Started Free", // Same as US 6 "features": { 7 "speed": "Lightning fast", 8 "security": "Bank-level security" 9 } 10 }, 11 "pricing": { 12 "currency": "GBP", 13 "monthly": "£79/month" // Different price/currency 14 } 15}
JSON1// locales/es-MX.json 2{ 3 "home": { 4 "title": "Bienvenido a Nuestra App", 5 "cta": "Comienza Gratis", 6 "features": { 7 "speed": "Increíblemente rápido", 8 "security": "Seguridad de nivel bancario" 9 } 10 }, 11 "pricing": { 12 "currency": "MXN", 13 "monthly": "content: ,799/mes" 14 } 15}
Paso 3: Globalización (Características específicas del mercado)
TSX1// Market configuration 2const markets = { 3 'us': { 4 paymentMethods: ['stripe', 'paypal'], 5 supportedCurrencies: ['USD'], 6 complianceDocuments: ['privacy-policy-ccpa'], 7 features: { 8 tipping: true, 9 cashPayments: false 10 } 11 }, 12 'eu': { 13 paymentMethods: ['stripe'], 14 supportedCurrencies: ['EUR', 'GBP'], 15 complianceDocuments: ['privacy-policy-gdpr', 'cookie-policy'], 16 features: { 17 tipping: false, 18 cashPayments: false 19 } 20 }, 21 'in': { 22 paymentMethods: ['razorpay', 'paytm', 'upi'], 23 supportedCurrencies: ['INR'], 24 complianceDocuments: ['privacy-policy'], 25 features: { 26 tipping: false, 27 cashPayments: true 28 } 29 } 30}; 31 32// Component 33function CheckoutPage() { 34 const locale = useLocale(); // 'en-US', 'en-GB', 'hi-IN', etc. 35 const market = locale.split('-')[1].toLowerCase(); 36 const config = markets[market] || markets['us']; 37 38 return ( 39 <div> 40 <PaymentMethods methods={config.paymentMethods} /> 41 {config.features.cashPayments && <CashOption />} 42 {config.features.tipping && <TipSelector />} 43 </div> 44 ); 45}
Errores comunes
1. 1. Confundir i18n con L10n
Incorrecto: "Hemos internacionalizado la app al español"
Correcto: "Internacionalizamos la app (ahora soporta varios idiomas) y luego la localizamos al español."
La internacionalización es independiente del idioma. La localización es específica del idioma.
2. Ignorar las variantes regionales
No trate el "español" como una sola cosa. Es:
es-ES(España)es-MX(México)es-AR(Argentina)es-CO(Colombia)
Cada uno tiene diferencias de vocabulario.
3. Traducir literalmente
Mala localización: Inglés: "No pongas todos los huevos en la misma cesta" Alemán (literal): "Lege nicht alle Eier in einen Korb" (sin sentido) Alemán (localizado): "Setze nicht alles auf eine Karte" (modismo correcto)
Recurra a traductores profesionales que comprendan el contexto cultural.
4. Olvidar la detección de localización
TSX1// ❌ Bad: Force English 2const locale = 'en'; 3 4// ✅ Good: Detect from browser 5const locale = navigator.language || 'en'; 6 7// ✅ Better: Let user choose, remember preference 8const locale = localStorage.getItem('locale') || navigator.language || 'en';
5. No Probar RTL
Si admite árabe/hebreo, pruebe RTL:
CSS/* Use logical properties */ margin-inline-start: 1rem; /* Not margin-left */ padding-inline-end: 1rem; /* Not padding-right */
TSX// Set direction attribute <html dir={i18n.dir()}> {/* 'ltr' or 'rtl' */}
Mejores prácticas
1. Traducciones de espacios de nombres
JSON1// ❌ Flat structure (hard to manage) 2{ 3 "button_save": "Save", 4 "button_cancel": "Cancel", 5 "button_delete": "Delete" 6} 7 8// ✅ Namespaced 9{ 10 "buttons": { 11 "save": "Save", 12 "cancel": "Cancel", 13 "delete": "Delete" 14 }, 15 "forms": { 16 "email_label": "Email", 17 "password_label": "Password" 18 } 19}
2. Utilizar rutas locales específicas
/en/pricing (English)
/es/precios (Spanish - translated URL)
/de/preise (German - translated URL)
Next.js config:
TypeScript1// next.config.ts 2export default { 3 i18n: { 4 locales: ['en', 'es', 'de'], 5 defaultLocale: 'en', 6 localeDetection: true 7 } 8};
3. Implementar Fallbacks
TSX1// If key missing in Spanish, fall back to English 2i18n.init({ 3 fallbackLng: 'en', 4 // If 'es-MX' missing, try 'es', then 'en' 5 fallbackLng: { 6 'es-MX': ['es', 'en'], 7 'es-AR': ['es', 'en'], 8 'default': ['en'] 9 } 10});
4. Traducciones de control de versiones
Almacenar traducciones en Git. Seguimiento de cambios:
Terminalgit log locales/es.json # See who changed what translation when
O utilizar un TMS con sincronización Git (como IntlPull).
5. Automatizar los flujos de trabajo de traducción
Terminal1# IntlPull example 2npx @intlpullhq/cli upload # Upload new English strings 3# Translators work in web UI 4npx @intlpullhq/cli download # Download translated strings
Evita la edición manual de JSON por parte de los traductores.
Estudio de un caso real: Aplicación SaaS
Escenario: React SaaS app, lanzamiento en EEUU, Europa, Latinoamérica.
Fase 1: Internacionalización (Semana 1-2)
Terminalnpm install next-intl
- Extraídas 1.200 cadenas de los componentes
- Configuración de
next-intlcon detección de configuración regional - Implementado formato de fecha / número con
IntlAPI - Probado con pseudo-localización (detectado errores de interfaz de usuario)
Resultado: Aplicación lista para la traducción.
Fase 2: Localización (Semana 3-4)
- Contratación de traductores para ES, FR, DE
- Cadenas traducidas (1.200 × 3 = 3.600 traducciones)
- Adaptación del texto de marketing (traducción no literal)
- Imágenes localizadas (fotos diferentes para el mercado de la UE)
Coste: 0,08 $/palabra × 1.200 palabras × 3 idiomas = 288 $
Resultado: Aplicación disponible en 4 idiomas.
Fase 3: Globalización (Semana 5-8)
- Stripe integrado para EE.UU./UE, MercadoPago para América Latina
- Configurar el cumplimiento de GDPR para la UE (banners de cookies, eliminación de datos)
- Precios localizados ($ para EE.UU., € para la UE, MXN para México)
- Lanzamiento de campañas de marketing regionales
Impacto en los ingresos: +180% de los mercados internacionales en el primer trimestre.
Cuándo hacer qué
| Etapa | Cuándo |
|---|---|
| Día 1 (o refactorizar la aplicación existente antes de traducirla) | |
| L10n** Antes del lanzamiento en un nuevo mercado | |
| En curso (a medida que se expande a nuevos mercados) |
**No traduzcas antes de internacionalizar. Tendrás que refactorizar todo más tarde.
Herramientas para cada fase
Internacionalización (i18n):
- React: react-i18next, react-intl
- Next.js: next-intl, next-i18next
- Vue: vue-i18n
- Svelte: svelte-i18n
Localización (L10n):
- Traducción: DeepL API, ChatGPT, traductores humanos
- Gestión: IntlPull, Lokalise, Phrase, Crowdin
Globalización (G11n):
- Pagos: Stripe (global), MercadoPago (LATAM), Razorpay (India)
- Análisis: Mixpanel, Amplitude (soporte multirregión)
- Cumplimiento: OneTrust (GDPR), TrustArc
**¿Listo para globalizarse?
IntlPull. Maneja cadenas i18n, flujos de trabajo L10n y despliegue G11n con actualizaciones OTA. Empiece a traducir en 5 minutos.
O construye tu propio sistema i18n si te sientes cómodo gestionando archivos de traducción manualmente.
