El sistema de localización integrado de Flutter usa archivos Application Resource Bundle (ARB) y el paquete intl para ofrecer experiencias totalmente nativas en cualquier idioma. Esta guía cubre desde la configuración del proyecto y detalles del formato ARB hasta el cambio de idioma, pluralización y automatización de traducciones con l10n.dev.
La localización en Flutter es el enfoque oficial para adaptar tu app a múltiples idiomas y regiones. Se basa en archivos ARB para almacenar cadenas traducidas y en el generador de código flutter_gen para producir accesores Dart con tipos seguros. En tiempo de ejecución, Flutter selecciona el archivo ARB correcto según la configuración regional del dispositivo, sin necesidad de reiniciar al cambiar el idioma programáticamente.
La canalización de localización de Flutter se controla con dos archivos de configuración: pubspec.yaml y l10n.yaml. Activa la generación de código en pubspec.yaml y apunta Flutter al directorio de tus archivos ARB.
Agrega flutter_localizations e intl como dependencias, luego activa la bandera generate para que Flutter genere automáticamente las clases Dart de localización a partir de tus archivos ARB.
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: trueColoca un archivo l10n.yaml en la raíz de tu proyecto para configurar el directorio ARB, el archivo plantilla y el nombre del archivo de salida generado.
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dartARB (Application Resource Bundle) es un formato basado en JSON diseñado específicamente para la internacionalización en Flutter. Cada clave corresponde a una cadena traducible, y las claves de metadatos opcionales (con prefijo @) contienen descripciones, definiciones de marcadores y contexto para traductores.
{
"@@locale": "en",
"@@last_modified": "2026-01-15T10:30:00Z",
"appTitle": "My App",
"@appTitle": {
"description": "The title of the application"
},
"welcome": "Welcome, {name}!",
"@welcome": {
"description": "Welcome message shown on the home screen",
"placeholders": {
"name": {
"type": "String",
"example": "Alice"
}
}
},
"unreadMessages": "{count, plural, =0{No unread messages} =1{1 unread message} other{{count} unread messages}}",
"@unreadMessages": {
"description": "Number of unread messages",
"placeholders": {
"count": {
"type": "int"
}
}
}
}Tras la traducción, las cadenas de la interfaz se localizan mientras la estructura de metadatos permanece intacta. l10n.dev actualiza @@locale y @@last_modified automáticamente.
{
"@@locale": "fr",
"@@last_modified": "2026-01-15T10:30:01Z",
"appTitle": "Mon Application",
"@appTitle": {
"description": "The title of the application"
},
"welcome": "Bienvenue, {name} !",
"@welcome": {
"description": "Welcome message shown on the home screen",
"placeholders": {
"name": {
"type": "String",
"example": "Alice"
}
}
},
"unreadMessages": "{count, plural, =0{Aucun message non lu} =1{1 message non lu} other{{count} messages non lus}}",
"@unreadMessages": {
"description": "Number of unread messages",
"placeholders": {
"count": {
"type": "int"
}
}
}
}Los archivos ARB siguen un patrón sencillo: un prefijo (por defecto app_) seguido del código de la configuración regional y la extensión .arb. Flutter y l10n.dev usan guiones bajos para separar los códigos de idioma y región.
# Default pattern (recommended)
app_en.arb
app_fr.arb
app_en_US.arb # Locale with region (underscore format)
app_zh_CN.arb # Chinese Simplified
# Custom prefix patterns also supported
my_app_en.arb
my_app_fr.arb
# Note: ARB files use underscores, not hyphens
# ✓ app_en_US.arb
# ✗ app_en-US.arbOrganiza todos tus archivos ARB dentro de una carpeta dedicada l10n dentro de lib/. El generador de código de Flutter los detecta automáticamente según la configuración arb-dir en l10n.yaml y genera clases Dart listas para usar.
lib/
├── l10n/
│ ├── app_en.arb ← Source (English)
│ ├── app_fr.arb ← French
│ ├── app_de.arb ← German
│ ├── app_ja.arb ← Japanese
│ ├── app_zh_CN.arb ← Chinese Simplified
│ └── app_es.arb ← Spanish
├── main.dart
└── ...
# Generated output (do not edit manually)
.dart_tool/
└── flutter_gen/
└── gen_l10n/
└── app_localizations.dartConecta la clase de localización Dart generada con MaterialApp proporcionando localizationsDelegates y supportedLocales. Flutter resolverá los datos ARB correctos para la configuración regional del dispositivo.
Pasa los cuatro delegados requeridos: tu AppLocalizations.delegate generado más los tres delegados del SDK de Flutter, y lista todas las configuraciones regionales que tu app soporta. Usa AppLocalizations.of(context)! en cualquier parte del árbol de widgets para acceder a las cadenas traducidas.
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'My App',
// Required delegates
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
// Supported locales
supportedLocales: AppLocalizations.supportedLocales,
home: const HomePage(),
);
}
}
// Use in a widget
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(title: Text(l10n.appTitle)),
body: Center(child: Text(l10n.welcome('Alice'))),
);
}
}Flutter permite cambiar la configuración regional de la app en tiempo de ejecución actualizando la propiedad locale en MaterialApp. Un patrón común es mantener un Locale en un StatefulWidget o en una solución de gestión de estado y exponer un callback para cambiarlo. El árbol de widgets se reconstruye automáticamente con la nueva configuración regional.
// Manage locale state at the app level
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Locale _locale = const Locale('en');
void _changeLocale(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: AppLocalizations.supportedLocales,
home: SettingsPage(onLocaleChange: _changeLocale),
);
}
}
// Language selector widget
class LanguageSelector extends StatelessWidget {
final void Function(Locale) onLocaleChange;
const LanguageSelector({super.key, required this.onLocaleChange});
@override
Widget build(BuildContext context) {
return DropdownButton<Locale>(
value: Localizations.localeOf(context),
items: AppLocalizations.supportedLocales
.map((locale) => DropdownMenuItem(
value: locale,
child: Text(locale.toLanguageTag()),
))
.toList(),
onChanged: (locale) {
if (locale != null) onLocaleChange(locale);
},
);
}
}Flutter usa la sintaxis de mensajes ICU para la pluralización dentro de los archivos ARB. El paquete intl maneja todas las categorías plurales CLDR, aplicando automáticamente la forma correcta según las reglas del idioma destino.
{
"cartItems": "{count, plural, =0{Your cart is empty} =1{1 item in your cart} other{{count} items in your cart}}",
"@cartItems": {
"description": "Cart item count",
"placeholders": {
"count": { "type": "int" }
}
},
"daysLeft": "{days, plural, =1{1 day left} other{{days} days left}}",
"@daysLeft": {
"description": "Days remaining",
"placeholders": {
"days": { "type": "int" }
}
}
}l10n.dev está diseñado para integrarse perfectamente con el flujo de trabajo ARB de Flutter. Sube tu archivo ARB fuente y recibe traducciones precisas y correctamente estructuradas:
Usa el paquete ai-l10n de npm para traducir tu archivo ARB fuente desde la línea de comandos o como parte de una canalización CI/CD. Instálalo una vez y traduce a cualquier número de idiomas con un solo comando.
# Install the CLI
npm install ai-l10n
# Translate your source ARB to multiple languages
npx ai-l10n translate lib/l10n/app_en.arb \
--languages fr,de,ja,zh_CN,es,koPuedes integrar ai-l10n directamente en tu proceso de compilación de Flutter para que las traducciones estén siempre actualizadas antes de que se compile la aplicación. Dos enfoques comunes son un script de package.json o un Makefile.
Añade un script de traducción y utiliza el hook de ciclo de vida prebuild de npm para ejecutarlo automáticamente antes de cada compilación. Ejecuta npm run build:android (o build:ios / build:web) y ai-l10n traducirá primero, y luego pasará el control a Flutter.
{
"scripts": {
"translate": "ai-l10n translate lib/l10n/app_en.arb --languages fr,de,ja,zh_CN,es,ko --update",
"prebuild": "npm run translate",
"build:android": "flutter build apk",
"build:ios": "flutter build ios",
"build:web": "flutter build web"
}
}Si tu equipo utiliza Make, declara un objetivo (target) de traducción y haz que cada objetivo de compilación dependa de él. Ejecutar make build-android (o build-ios / build-all) traducirá todos los idiomas de destino antes de invocar flutter build.
LANGUAGES = fr,de,ja,zh_CN,es,ko
translate:
npx ai-l10n translate lib/l10n/app_en.arb --languages $(LANGUAGES) --update
build-android: translate
flutter build apk
build-ios: translate
flutter build ios
build-web: translate
flutter build web
build-all: translate
flutter build apk
flutter build ios
flutter build webPara integración CI/CD, actualizaciones incrementales, traducción por lotes en múltiples archivos y ejemplos de flujos de trabajo en GitHub Actions, consulta la Guía de Automatización de Localización.
La extensión l10n.dev para VS Code trae la traducción de archivos ARB de Flutter directamente a tu editor. Haz clic derecho en cualquier archivo ARB y tradúcelo a tus idiomas objetivo sin salir de VS Code.
Aquí tienes un ejemplo en vivo de la traducción de un archivo ARB de Flutter al uzbeko dentro de VS Code:

¿Listo para llegar a usuarios globales? Puedes traducir archivos ARB directamente en el espacio de trabajo l10n.dev, automatizar con la CLI de npm o traducir directamente dentro de VS Code:
Descubre por qué la traducción potenciada por IA es mejor para archivos de i18n que los métodos tradicionales.
Integra la localización potenciada por IA directamente en tu pipeline de CI/CD.
Incorpora la localización de IA en tu flujo de trabajo con nuestras extensiones y complementos.
¡Gracias por usar l10n.dev para localizar tu app Flutter! 🚀
Si esta guía te fue útil, compártela con otros desarrolladores Flutter que quieran llegar a una audiencia global.
Juntos, podemos hacer que las apps Flutter sean más inclusivas y estén listas para el mundo.