Skip to content

Cómo Traducir una App Flutter: Guía Completa

Aprende cómo localizar tu app Flutter usando Dart y el paquete intl. Esta guía completa cubre la localización de cadenas, pluralización, formato de fechas y mejores prácticas para la traducc

  • date icon

    14 de noviembre de 2025

  • 05 min de lectura
Cómo Traducir una App Flutter: Guía Completa

Traducir tu app Flutter es esencial para llegar a una audiencia global. Flutter proporciona excelente soporte integrado para la localización a través del paquete intl y archivos ARB (Application Resource Bundle). Esta guía te guiará a través del proceso de traducir una app Flutter usando Dart.

Entendiendo la Localización en Flutter

Flutter utiliza archivos ARB (Application Resource Bundle) para almacenar traducciones. Estos archivos similares a JSON contienen pares clave-valor para cada idioma. El paquete intl de Flutter maneja la localización automáticamente basándose en la configuración de idioma del dispositivo del usuario.

Paso 1: Añadir Dependencias

Primero, añade los paquetes necesarios a tu pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.19.0

flutter:
  generate: true

Ejecuta flutter pub get para instalar los paquetes.

Paso 2: Configurar l10n.yaml

Crea un archivo l10n.yaml en la raíz de tu proyecto para configurar la localización:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

Paso 3: Crear Archivos ARB

Crea un directorio lib/l10n y añade archivos ARB para cada idioma:

lib/l10n/app_en.arb (Inglés - por defecto):

{
  "@@locale": "en",
  "appName": "My App",
  "@appName": {
    "description": "The application name"
  },
  "welcomeMessage": "Welcome to our app!",
  "@welcomeMessage": {
    "description": "Welcome message displayed on home screen"
  },
  "buttonSubmit": "Submit",
  "@buttonSubmit": {
    "description": "Submit button label"
  },
  "errorNetwork": "Network error. Please try again.",
  "@errorNetwork": {
    "description": "Network error message"
  },
  "itemsCount": "{count, plural, =0{No items} one{1 item} other{{count} items}}",
  "@itemsCount": {
    "description": "Number of items",
    "placeholders": {
      "count": {
        "type": "int"
      }
    }
  },
  "userGreeting": "Hello, {name}! You have {messageCount, plural, =0{no messages} one{1 message} other{{messageCount} messages}}.",
  "@userGreeting": {
    "description": "Greeting with user name and message count",
    "placeholders": {
      "name": {
        "type": "String"
      },
      "messageCount": {
        "type": "int"
      }
    }
  }
}

lib/l10n/app_es.arb (Español):

{
  "@@locale": "es",
  "appName": "Mi Aplicación",
  "welcomeMessage": "¡Bienvenido a nuestra aplicación!",
  "buttonSubmit": "Enviar",
  "errorNetwork": "Error de red. Por favor, inténtalo de nuevo.",
  "itemsCount": "{count, plural, =0{No hay elementos} one{1 elemento} other{{count} elementos}}",
  "userGreeting": "¡Hola, {name}! Tienes {messageCount, plural, =0{no hay mensajes} one{1 mensaje} other{{messageCount} mensajes}}."
}

lib/l10n/app_fr.arb (Francés):

{
  "@@locale": "fr",
  "appName": "Mon Application",
  "welcomeMessage": "Bienvenue dans notre application!",
  "buttonSubmit": "Soumettre",
  "errorNetwork": "Erreur réseau. Veuillez réessayer.",
  "itemsCount": "{count, plural, =0{Aucun élément} one{1 élément} other{{count} éléments}}",
  "userGreeting": "Bonjour, {name}! Vous avez {messageCount, plural, =0{aucun message} one{1 message} other{{messageCount} messages}}."
}

Paso 4: Generar Archivos de Localización

Ejecuta el generador de código:

flutter gen-l10n

O usa:

flutter pub run intl_utils:generate

Esto genera app_localizations.dart y archivos específicos de idioma en .dart_tool/flutter_gen/gen_l10n/.

Paso 5: Configurar MaterialApp

Actualiza tu main.dart para habilitar la localización:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Localization Demo',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en'), // English
        Locale('es'), // Spanish
        Locale('fr'), // French
      ],
      home: const HomePage(),
    );
  }
}

Paso 6: Usar Cadenas Localizadas

Accede a las cadenas localizadas usando AppLocalizations.of(context):

Antes:

Text('Welcome to our app!')

Después:

Text(AppLocalizations.of(context)!.welcomeMessage)

O con un enfoque null-safe:

final l10n = AppLocalizations.of(context);
if (l10n != null) {
  Text(l10n.welcomeMessage)
}

Paso 7: Manejar Formato de Cadenas con Variables

Usa placeholders en archivos ARB y Flutter maneja el formato:

Archivo ARB:

{
  "userGreeting": "Hello, {name}!",
  "@userGreeting": {
    "placeholders": {
      "name": {
        "type": "String"
      }
    }
  }
}

Dart:

Text(AppLocalizations.of(context)!.userGreeting('John'))
// Inglés: "Hello, John!"
// Español: "¡Hola, John!"

Paso 8: Pluralización

Flutter soporta pluralización usando el formato de mensaje ICU:

Archivo ARB:

{
  "itemsCount": "{count, plural, =0{No items} one{1 item} other{{count} items}}"
}

Dart:

Text(AppLocalizations.of(context)!.itemsCount(5))
// Inglés: "5 items"
// Español: "5 elementos"

Text(AppLocalizations.of(context)!.itemsCount(1))
// Inglés: "1 item"
// Español: "1 elemento"

Text(AppLocalizations.of(context)!.itemsCount(0))
// Inglés: "No items"
// Español: "No hay elementos"

Paso 9: Formatear Fechas y Números

Usa el paquete intl para el formato localizado:

Fechas:

import 'package:intl/intl.dart';

final date = DateTime.now();
final formatter = DateFormat.yMMMMEEEEd(Intl.getCurrentLocale());
final localizedDate = formatter.format(date);
// Inglés: "Wednesday, March 20, 2025"
// Español: "miércoles, 20 de marzo de 2025"

Números:

import 'package:intl/intl.dart';

final number = 1234.56;
final formatter = NumberFormat.decimalPattern(Intl.getCurrentLocale());
final localizedNumber = formatter.format(number);
// Inglés: "1,234.56"
// Español: "1.234,56"

Moneda:

import 'package:intl/intl.dart';

final amount = 1234.56;
final formatter = NumberFormat.currency(locale: Intl.getCurrentLocale());
final localizedCurrency = formatter.format(amount);
// Inglés (US): "$1,234.56"
// Español (ES): "1.234,56 €"

Paso 10: Manejar Idiomas de Derecha a Izquierda (RTL)

Flutter maneja automáticamente los diseños RTL. Usa el widget Directionality si es necesario:

Directionality(
  textDirection: TextDirection.rtl, // o TextDirection.ltr
  child: YourWidget(),
)

O detecta automáticamente:

final locale = Localizations.localeOf(context);
final isRTL = locale.languageCode == 'ar' || locale.languageCode == 'he';

Paso 11: Probar tu Localización

Usando Flutter DevTools:

  1. Ejecuta tu app
  2. Abre DevTools
  3. Ve a la pestaña Inspector
  4. Cambia el locale en la configuración del dispositivo

Usando Configuración del Dispositivo:

  1. Ve a Settings > Language & Region del dispositivo
  2. Cambia el idioma del dispositivo
  3. Reinicia tu app

Programáticamente (para pruebas):

import 'package:flutter/material.dart';

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Locale _locale = const Locale('en');

  void _changeLanguage(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: _locale,
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en'),
        Locale('es'),
        Locale('fr'),
      ],
      home: LanguageSelector(
        onLanguageChanged: _changeLanguage,
      ),
    );
  }
}

Mejores Prácticas

1. Usar Claves Descriptivas

Malo:

{
  "msg1": "Submit"
}

Bueno:

{
  "buttonSubmit": "Submit",
  "@buttonSubmit": {
    "description": "Submit button label"
  }
}

2. Proporcionar Contexto en Archivos ARB

Siempre incluye entradas de metadatos @ para ayudar a los traductores:

{
  "deleteButton": "Delete",
  "@deleteButton": {
    "description": "Button to delete an item. Shown in the item detail view."
  }
}

3. Evitar Concatenación de Cadenas

Malo:

Text(AppLocalizations.of(context)!.hello + ' ' + name)

Bueno:

{
  "helloUser": "Hello, {name}!",
  "@helloUser": {
    "placeholders": {
      "name": {"type": "String"}
    }
  }
}
Text(AppLocalizations.of(context)!.helloUser(name))

4. Usar Pluralización Correctamente

Siempre usa el formato plural ICU para elementos contables:

{
  "messagesCount": "{count, plural, =0{No messages} one{1 message} other{{count} messages}}"
}

5. Probar Longitudes de Cadenas

Algunos idiomas son más largos que otros. Diseña tu UI para acomodar:

  • Alemán y finlandés: 30-50% más largos que el inglés
  • Idiomas asiáticos: Pueden necesitar más espacio vertical
  • Árabe y hebreo: Consideraciones de diseño RTL

6. Manejar Traducciones Faltantes

Flutter recurre al locale por defecto si falta una traducción. Siempre proporciona un fallback:

final l10n = AppLocalizations.of(context);
final text = l10n?.welcomeMessage ?? 'Welcome'; // Fallback

Errores Comunes

1. Olvidar Ejecutar la Generación de Código

Después de actualizar archivos ARB, siempre ejecuta:

flutter gen-l10n

2. No Incluir Todos los Delegados Requeridos

Asegúrate de incluir los cuatro delegados:

localizationsDelegates: const [
  AppLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
  GlobalCupertinoLocalizations.delegate,
],

3. Codificar Cadenas de Formato

Malo:

Text('\$${amount.toStringAsFixed(2)}')

Bueno:

final formatter = NumberFormat.currency(locale: Intl.getCurrentLocale());
Text(formatter.format(amount))

4. No Probar Casos Extremos

Prueba con:

  • Cadenas muy largas
  • Caracteres especiales
  • Números y fechas
  • Formas plurales (0, 1, muchos)
  • Idiomas RTL

Avanzado: Cambio Dinámico de Idioma

Para permitir a los usuarios cambiar el idioma dentro de la app:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LocaleProvider extends ChangeNotifier {
  Locale _locale = const Locale('en');
  
  Locale get locale => _locale;
  
  Future<void> loadLocale() async {
    final prefs = await SharedPreferences.getInstance();
    final languageCode = prefs.getString('language_code') ?? 'en';
    _locale = Locale(languageCode);
    notifyListeners();
  }
  
  Future<void> setLocale(Locale locale) async {
    if (_locale == locale) return;
    
    _locale = locale;
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString('language_code', locale.languageCode);
    notifyListeners();
  }
}

Uso:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => LocaleProvider()..loadLocale(),
      child: Consumer<LocaleProvider>(
        builder: (context, localeProvider, _) {
          return MaterialApp(
            locale: localeProvider.locale,
            localizationsDelegates: const [
              AppLocalizations.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            supportedLocales: const [
              Locale('en'),
              Locale('es'),
              Locale('fr'),
            ],
            home: const HomePage(),
          );
        },
      ),
    );
  }
}

Usando con GetX (Alternativa)

Si estás usando GetX para gestión de estado:

import 'package:get/get.dart';

class LocaleController extends GetxController {
  var locale = const Locale('en').obs;
  
  void changeLocale(Locale newLocale) {
    locale.value = newLocale;
    Get.updateLocale(newLocale);
  }
}

Conclusión

Localizar tu app Flutter es sencillo cuando sigues estos pasos:

  1. Añade los paquetes flutter_localizations e intl
  2. Crea archivos ARB para cada idioma en lib/l10n/
  3. Configura l10n.yaml y ejecuta la generación de código
  4. Configura localizationsDelegates en MaterialApp
  5. Usa AppLocalizations.of(context) en toda tu app
  6. Maneja la pluralización con el formato de mensaje ICU
  7. Formatea fechas y números usando el paquete intl
  8. Prueba exhaustivamente en todos los idiomas soportados

Siguiendo estas prácticas, crearás una app que proporciona una experiencia nativa para usuarios de todo el mundo, expandiendo significativamente tu base de usuarios potencial.

Optimiza tu Flujo de Trabajo de Localización Flutter

Gestionar traducciones para múltiples idiomas puede volverse complejo a medida que tu app crece. Considera usar una plataforma de gestión de traducciones para:

  • Colaborar con traductores
  • Mantener las traducciones sincronizadas con tu código base
  • Automatizar el flujo de trabajo de traducción
  • Mantener la consistencia en todos los idiomas
  • Generar archivos ARB automáticamente

¿Listo para llevar tu app Flutter a nivel global? Explora la plataforma de localización de AZbox y optimiza tu flujo de trabajo de traducción:

Ver Planes y Precios de AZbox

Blog

Últimas Publicaciones

Descubre nuestros últimos artículos y actualizaciones.

Servicios de localización de videojuegos: guía 2026 para llevar tu juego al mundo
date icon

21 de febrero de 2026

05 min de lectura

Servicios de localización de videojuegos: guía 2026 para llevar tu juego al mundo

Llevar tu juego a nivel global no es solo traducir texto: es hacer que los jugadores de cada mercado sientan que el jueg

Leer más
Software de localización de apps: guía 2026 para elegir y usar la herramienta adecuada
date icon

20 de febrero de 2026

05 min de lectura

Software de localización de apps: guía 2026 para elegir y usar la herramienta adecuada

Si estás llevando tu app más allá de un solo idioma, el software de localización de apps es la palanca que convierte

Leer más
Traducción para SaaS: Guía Completa para Localizar Tu Producto
date icon

15 de febrero de 2026

04 min de lectura

Traducción para SaaS: Guía Completa para Localizar Tu Producto

La traducción para SaaS ya no es opcional. Si quieres crecer más allá de tu mercado local, necesitas una estrategia

Leer más
Fondo de llamada a la acción

Comienza el Crecimiento Global Hoy

Sube tus archivos de idioma, recibe las traducciones y mantén cada idioma sincronizado mientras tu producto sigue cambiando.

Comenzar - Es Gratis