Skip to main content

Ang Kumpletong Gabay sa Flutter Localization

Mula sa mga ARB file hanggang sa RTL support: i-localize ang Flutter app ninyo gamit ang easy_localization, pangasiwaan ang plural para sa bawat wika, at i-automate ang mga salin gamit ang AI.

1

I-install ang easy_localization

Idagdag ang easy_localization package sa pubspec.yaml. Ito ang pinakasikat na Flutter i18n package na may suporta para sa mga ARB/JSON file, plural, at context extension. Idagdag din ang flutter_localizations mula sa SDK para sa locale-aware na pag-format ng mga petsa, numero, at text direction.

Nagbibigay ang easy_localization ng mga context extension tulad ng context.tr() at 'key'.tr() para sa mas maigsi na pag-access sa mga salin. Pinangangasiwaan nito ang paglo-load ng locale, persistence, at hot-reloading ng mga translation file habang nagde-develop.
pubspec.yaml
dependencies:
  easy_localization: ^3.0.7
  flutter_localizations:
    sdk: flutter
2

Gumawa ng Mga ARB Translation File

Ang Application Resource Bundle (ARB) file ang standard na localization format para sa Flutter. Bawat file ay may mga key-value pair na may opsyonal na metadata na naglalarawan ng mga placeholder, plural rule, at konteksto para sa mga tagasalin. Gumawa ng tig-isang file bawat locale sa inyong assets/translations directory.

assets/translations/en.arb
{
  "@@locale": "en",
  "appTitle": "My App",
  "@appTitle": {
    "description": "The title of the application"
  },
  "greeting": "Hello, {name}!",
  "@greeting": {
    "description": "Greeting with user name",
    "placeholders": {
      "name": {
        "type": "String",
        "example": "Alice"
      }
    }
  },
  "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
  "@itemCount": {
    "description": "Number of items in the cart",
    "placeholders": {
      "count": {
        "type": "num",
        "format": "compact"
      }
    }
  }
}
Ang mga key na may @-prefix (tulad ng @greeting) ay metadata—iniilarawan nila ang string sa itaas nila. Isama ang mga uri ng placeholder at mga halimbawa para matulungan ang mga tagasalin na makagawa ng tumpak na salin. Inaalis ang mga metadata key sa runtime at wala itong anumang overhead.
3

I-configure ang App

I-wrap ang app ninyo sa EasyLocalization widget. Pinamamahalaan nito ang locale state, naglo-load ng mga salin mula sa inyong asset file, at nagbibigay ng mga locale delegate na kailangan ng MaterialApp. Ang tatlong kinakailangang delegate property ay localizationsDelegates, supportedLocales, at locale—lahat ay available sa pamamagitan ng mga context extension.

lib/main.dart
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(
    EasyLocalization(
      supportedLocales: [
        Locale('en'),
        Locale('ar'),
        Locale('ja'),
        Locale('de'),
      ],
      path: 'assets/translations',  // Path to your ARB/JSON files
      fallbackLocale: Locale('en'),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: context.localizationDelegates,
      supportedLocales: context.supportedLocales,
      locale: context.locale,
      home: HomePage(),
    );
  }
}
"Easy Localization not initialized" — ibig sabihin ng error na ito ay nakalimutan ninyong tawagin ang EasyLocalization.ensureInitialized() bago ang runApp(). Dapat ninyo itong i-await pagkatapos ng WidgetsFlutterBinding.ensureInitialized() at bago tumawag ng runApp().
4

Isalin ang Mga Widget

Gamitin ang .tr() extension method sa mga string key para makuha ang isinaling text sa anumang widget. Para sa plural, gamitin ang .plural() kasama ang count value. Nagbibigay ang easy_localization ng parehong string extension syntax ('key'.tr()) at context method syntax (context.tr('key')).

lib/widgets/home_page.dart
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('appTitle'.tr()),   // Simple key
      ),
      body: Column(
        children: [
          // String with variable interpolation
          Text('greeting'.tr(args: ['Alice'])),

          // Named arguments
          Text('greeting'.tr(namedArgs: {'name': 'Alice'})),

          // Plural form
          Text('itemCount'.plural(3)),
        ],
      ),
    );
  }
}
Kung nagbabalik ang mga salin ng raw key sa halip na isinaling text, suriin: 1) Ang EasyLocalization widget ang dapat na nagwawrap sa MaterialApp, hindi baliktad. 2) Nakadeklara ang mga translation file sa pubspec.yaml sa ilalim ng assets. 3) Tumutugma ang file path sa EasyLocalization sa tunay ninyong istruktura ng directory.
5

Pangasiwaan ang Plural at Mga Variable

Gumagamit ang Flutter ng ICU MessageFormat para sa plural—kapareho ng standard na ginagamit sa iOS, Android, at web. I-define ang mga plural form gamit ang {count, plural, ...} syntax sa inyong mga ARB file. Kailangan ng bawat wika ang sarili nitong set ng form batay sa CLDR plural rules. May 6 na form ang Arabic, 4 ang Russian, at 1 ang Japanese.

Plural forms by language
// English: 3 useful forms (=0, =1, other)
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"

// Arabic: 6 forms (=0, =1, =2, few, many, other)
"itemCount": "{count, plural, =0{لا عناصر} =1{عنصر واحد} =2{عنصران} few{{count} عناصر} many{{count} عنصرًا} other{{count} عنصر}}"

// Japanese: 1 form (other)
"itemCount": "{count, plural, other{{count}個のアイテム}}"

// German: 2 forms (=1, other)
"itemCount": "{count, plural, =1{1 Artikel} other{{count} Artikel}}"

// Russian: 3 forms (one, few, many)
"itemCount": "{count, plural, =0{Нет товаров} one{{count} товар} few{{count} товара} many{{count} товаров} other{{count} товаров}}"
Variables and named arguments
// Simple variable
"welcome": "Welcome, {name}!"

// Multiple variables
"orderStatus": "Order #{orderId} — {status}"

// Variable in plural context
"unreadMessages": "{count, plural, =0{No unread messages} =1{1 unread message from {sender}} other{{count} unread messages}}"

// In widgets:
Text('welcome'.tr(namedArgs: {'name': userName}));
Text('orderStatus'.tr(namedArgs: {'orderId': '1234', 'status': 'Shipped'}));
Text('unreadMessages'.plural(count, namedArgs: {'sender': senderName}));
Huwag kailanman i-hardcode ang singular/plural logic gamit ang if (count == 1). Sa mga wikang tulad ng French, itinuturing na singular ang 0. Ang Russian, Polish, at Arabic ay may mga plural form na wala sa English. Palaging gamitin ang ICU plural syntax at hayaang ang framework ang pumili ng tamang anyo.
6

Suportahan ang Mga Wikang RTL

Awtomatikong minimirror ng Flutter ang buong layout kapag ang locale ay right-to-left na wika (Arabic, Hebrew, Persian, Urdu). Ngunit dapat gumamit ang code ninyo ng mga directional-aware na widget at property para gumana nang tama ang mirroring. Palitan ang mga naka-hardcode na left/right ng katumbas na start/end.

lib/widgets/adaptive_layout.dart
import 'package:flutter/material.dart';

class AdaptiveLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final isRtl = Directionality.of(context) == TextDirection.rtl;

    return Scaffold(
      body: Row(
        children: [
          // Use start/end instead of left/right
          Expanded(
            child: Padding(
              padding: EdgeInsetsDirectional.only(
                start: 16.0,  // Leading edge (left in LTR, right in RTL)
                end: 8.0,     // Trailing edge
              ),
              child: Text('content'.tr()),
            ),
          ),
          // Flip icons for RTL
          Icon(
            isRtl ? Icons.arrow_back : Icons.arrow_forward,
          ),
        ],
      ),
    );
  }
}
RTL-aware widget patterns
// Use Directional widgets for RTL-aware layouts
EdgeInsetsDirectional.only(start: 16, end: 8)   // Not EdgeInsets.only(left: 16, right: 8)
AlignmentDirectional.centerStart                  // Not Alignment.centerLeft
BorderRadiusDirectional.only(topStart: Radius.circular(8))

// Automatically mirrors when locale changes to Arabic, Hebrew, etc.
// No conditional logic needed — Flutter handles text direction from locale
Subukan ang RTL sa pamamagitan ng pansamantalang pag-set ng app locale ninyo sa Arabic (Locale('ar')). Minimirror ng Flutter ang buong UI—magbubukas mula kanan ang navigation drawer, magfa-flip ang back arrow, at mag-a-align sa kanan ang text. Gumamit ng EdgeInsetsDirectional, AlignmentDirectional, at BorderRadiusDirectional para matiyak na tama ring minimirror ang inyong mga custom layout.
7

Smart na Locale Fallback Chain

Bilang default, kapag nawawala ang pt-BR translation, direktang nagfa-fallback ang Flutter sa English—nilalaktawan ang pt-PT na posibleng may tamang salin. Inaayos ito ng locale_chain package sa pamamagitan ng configurable fallback chain. Isang linya ng setup, walang migration—gagana na agad ang mga umiiral ninyong .tr() call.

lib/main.dart with LocaleChain
import 'package:locale_chain/locale_chain.dart';
import 'package:locale_chain/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();
  LocaleChain.configure();  // Enable smart fallback chains

  runApp(
    EasyLocalization(
      supportedLocales: [
        Locale('en'),
        Locale('pt', 'BR'),
        Locale('pt', 'PT'),
        Locale('es'),
        Locale('es', 'MX'),
      ],
      path: 'assets/translations',
      assetLoader: LocaleChainAssetLoader(  // Swap in the chain loader
        baseLoader: RootBundleAssetLoader(),
      ),
      fallbackLocale: Locale('en'),
      child: MyApp(),
    ),
  );
}

// Result: pt-BR user sees pt-PT translations when pt-BR keys are missing,
// instead of falling back directly to English.
Custom fallback configuration
// Override specific chains while keeping built-in defaults
LocaleChain.configure(
  fallbacks: {
    'pt-BR': ['pt-PT', 'pt'],      // pt-BR → pt-PT → pt → en
    'es-MX': ['es-419', 'es'],     // es-MX → es-419 → es → en
    'fr-CA': ['fr'],               // fr-CA → fr → en
  },
);

// Or replace all defaults with your own chains
LocaleChain.configure(
  fallbacks: {
    'zh-Hant-HK': ['zh-Hant-TW', 'zh-Hans'],
    'pt-BR': ['pt-PT', 'pt'],
  },
  mergeDefaults: false,  // Only your chains, no built-in defaults
);
Kasama sa locale_chain ang mga built-in fallback chain para sa mga regional variant ng Portuguese, Spanish, French, German, Italian, Dutch, Norwegian, at Malay. Makikita ng pt-BR user ang pt-PT content bago ang English. Makikita ng es-MX user ang es-419, pagkatapos es, bago ang default locale.
8

I-automate ang Mga Salin

Kapag kumpleto na ang localization setup ninyo, isalin ang inyong mga ARB file gamit ang AI. Sa inyong IDE, hilingin sa AI assistant na isalin ang source ARB file ninyo, o gamitin ang i18n Agent CLI sa inyong CI/CD pipeline. Nagbibigay ang ARB metadata (placeholders, descriptions) ng konteksto na nagpapabuti sa kalidad ng pagsasalin.

Terminal
# In your IDE, ask your AI assistant:
> Translate assets/translations/en.arb to Arabic, Japanese, and German

✓ ar.arb created (1.4s)
✓ ja.arb created (1.2s)
✓ de.arb created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate assets/translations/en.arb --lang ar,ja,de
Magsalin nang paunti-unti—kapag nagdagdag kayo ng mga bagong key sa source ARB file ninyo, isalin lamang ang diff sa halip na i-regenerate ang lahat ng file. Napapanatili nito ang anumang saling nasuri na ng tao at nananatiling buo ang ARB metadata ninyo.

I-automate ang Kalidad ng Pagsasalin

Matukoy ang mga nawawalang key at sirang placeholder bago ma-ship gamit ang i18n-validate. Subukan ang UI ninyo gamit ang mga pseudo-translation sa i18n-pseudo bago dumating ang mga tunay na salin.

Mga Karaniwang Pagkakamali

Hindi Natagpuan ang Mga Translation File sa Runtime

Dapat nakadeklara ang inyong mga ARB/JSON file sa pubspec.yaml sa ilalim ng assets section. Kapag nalampasan ang hakbang na ito, hindi mahahanap ng Flutter ang mga file sa runtime kahit na umiiral ang mga ito sa disk. Idagdag: assets: - assets/translations/

Hindi Wastong ARB File Syntax

Mahigpit na JSON ang mga ARB file—walang trailing comma, walang single quote, walang comment. Kahit isang syntax error lang ay tahimik na makakapigil sa paglo-load ng buong file. I-validate ang inyong mga ARB file gamit ang JSON linter bago mag-debug ng mga isyu sa pagsasalin.

Hindi Lumalabas ang Mga Pagbabago sa Salin sa Hot Reload

Naka-cache sa memory ang mga salin sa easy_localization. Ang pagdaragdag ng mga bagong key o pagbabago ng mga umiiral na salin ay maaaring mangailangan ng full hot restart (hindi hot reload) bago magkabisa. Habang nagde-develop, gumamit ng hot restart (Shift+R) pagkatapos mag-edit ng mga translation file.

Nakasasira sa RTL ang Naka-hardcode na Left/Right

Ang paggamit ng EdgeInsets.only(left: 16) sa halip na EdgeInsetsDirectional.only(start: 16) ay pumipigil sa Flutter na i-mirror ang layout ninyo para sa mga RTL na wika. Hanapin sa codebase ninyo ang EdgeInsets, Alignment, at BorderRadius na walang Directional suffix.

Inirerekomendang Istruktura ng File

Project Structure
my_flutter_app/
├── assets/
│   └── translations/
│       ├── en.arb          # Source language (English)
│       ├── ar.arb          # Arabic (with 6 plural forms)
│       ├── de.arb          # German
│       ├── ja.arb          # Japanese
│       ├── pt-BR.arb       # Brazilian Portuguese
│       └── pt-PT.arb       # European Portuguese
├── lib/
│   ├── main.dart           # App entry with EasyLocalization
│   ├── app.dart            # MaterialApp with locale delegates
│   └── widgets/
│       └── language_switcher.dart
├── pubspec.yaml            # Dependencies
└── analysis_options.yaml

Subukan ang i18n Agent Ngayon

I-drop dito ang inyong translation file

JSON, YAML, PO, XML, CSV, Markdown, Properties

o i-click para mag-browse

Mga target language

Hindi kailangan ang signupInstant na estimate

Locale Fallback gamit ang locale_chain

Kapag nawawala ang translation key sa isang regional locale tulad ng pt-BR, direktang lumilipat ang Flutter sa template language sa halip na suriin muna ang parent locale na pt.

Terminal
flutter pub add locale_chain
Configuration
import 'package:locale_chain/locale_chain.dart';

LocaleChain.configure(fallbacks: {
  'pt-BR': ['pt', 'en'],
  'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
});

LocaleChainAssetLoader(baseLoader: RootBundleAssetLoader());

Tingnan ang aming Locale Fallback Guide para sa kumpletong listahan ng mga suportadong framework at 75 built-in chain. Learn more →

Mga Madalas Itanong