Pusat Bantuan

Lokalisasi Flutter: File ARB, Intl & Otomatisasi

Sistem lokalisasi bawaan Flutter menggunakan file Application Resource Bundle (ARB) dan paket intl untuk memberikan pengalaman yang sepenuhnya asli dalam bahasa apa pun. Panduan ini mencakup semuanya, mulai dari pengaturan proyek dan detail format ARB hingga peralihan bahasa, penjamakan, dan otomatisasi terjemahan dengan l10n.dev.

Apa itu Lokalisasi Flutter?

Lokalisasi Flutter adalah pendekatan resmi untuk mengadaptasi aplikasi Anda ke berbagai bahasa dan wilayah. Sistem ini mengandalkan file ARB untuk menyimpan string terjemahan dan generator kode flutter_gen untuk menghasilkan aksesor Dart yang aman terhadap tipe data. Saat runtime, Flutter memilih file ARB yang tepat berdasarkan lokal perangkat - tidak perlu memulai ulang saat mengganti lokal secara terprogram.

Pengaturan Proyek

Alur kerja lokalisasi Flutter didorong oleh dua file konfigurasi: pubspec.yaml dan l10n.yaml. Aktifkan pembuatan kode di pubspec.yaml dan arahkan Flutter ke direktori ARB Anda.

1. Perbarui pubspec.yaml

Tambahkan flutter_localizations dan intl sebagai dependensi, lalu aktifkan flag generate agar Flutter secara otomatis membuat kelas lokalisasi Dart dari file ARB Anda.

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

flutter:
  generate: true

2. Buat l10n.yaml

Tempatkan file l10n.yaml di root proyek Anda untuk mengonfigurasi direktori ARB, file template, dan nama file output yang dihasilkan.

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

Format File ARB

ARB (Application Resource Bundle) adalah format berbasis JSON yang dirancang khusus untuk internasionalisasi Flutter. Setiap kunci memetakan ke string yang dapat diterjemahkan, dan kunci metadata opsional (diawali dengan @) memuat deskripsi, definisi placeholder, dan konteks untuk penerjemah.

  • @@locale: Mendeklarasikan lokal untuk file tersebut (misalnya, "en", "fr", "zh_CN"). l10n.dev secara otomatis memperbarui ini ke kode bahasa target.
  • @@last_modified: Stempel waktu modifikasi terakhir. l10n.dev secara otomatis mengaturnya ke stempel waktu UTC saat ini saat membuat file terjemahan.
  • @key metadata: Entri metadata seperti deskripsi, contoh, dan placeholder TIDAK diterjemahkan secara default - entri tersebut tetap tidak berubah untuk menjaga konteks bagi penerjemah. Aktifkan pengaturan translateMetadata jika Anda ingin metadata ini diterjemahkan.
  • Placeholder dan pesan ICU: String dapat berisi placeholder bernama ({name}) dan sintaks pesan ICU untuk penjamakan dan seleksi - semuanya dipertahankan dengan benar selama penerjemahan.

File ARB sumber (Inggris)

{
  "@@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"
      }
    }
  }
}

File ARB terjemahan (Prancis)

Setelah diterjemahkan, string UI dilokalkan sementara struktur metadata tetap utuh. l10n.dev memperbarui @@locale dan @@last_modified secara otomatis.

{
  "@@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"
      }
    }
  }
}

Konvensi Penamaan File

File ARB mengikuti pola penamaan yang lugas: awalan (defaultnya app_) diikuti oleh kode lokal dan ekstensi .arb. Flutter dan l10n.dev menggunakan garis bawah untuk memisahkan kode bahasa dan wilayah.

File ARB menggunakan garis bawah, bukan tanda hubung - tulis app_en_US.arb dan app_zh_CN.arb, bukan app_en-US.arb atau app_zh-CN.arb.
# 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.arb

Struktur Proyek

Atur semua file ARB Anda di dalam folder l10n khusus di dalam lib/. Generator kode Flutter mengambilnya secara otomatis berdasarkan pengaturan arb-dir di l10n.yaml, dan menghasilkan kelas Dart yang siap digunakan.

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.dart

Inisialisasi

Hubungkan kelas lokalisasi Dart yang dihasilkan dengan MaterialApp dengan menyediakan localizationsDelegates dan supportedLocales. Flutter kemudian akan menyelesaikan data ARB yang tepat untuk lokal perangkat.

Pengaturan MaterialApp

Berikan empat delegasi yang diperlukan - AppLocalizations.delegate yang Anda buat ditambah tiga delegasi SDK Flutter - dan daftarkan setiap lokal yang didukung aplikasi Anda. Gunakan AppLocalizations.of(context)! di mana saja di dalam pohon widget untuk mengakses string terjemahan.

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'))),
    );
  }
}

Peralihan Bahasa saat Runtime

Flutter memungkinkan Anda mengganti lokal aplikasi saat runtime dengan memperbarui properti locale pada MaterialApp. Pola yang umum adalah menyimpan Locale dalam StatefulWidget atau solusi manajemen status dan mengekspos callback untuk mengubahnya. Pohon widget secara otomatis membangun ulang dengan lokal baru.

// 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);
      },
    );
  }
}

Penjamakan

Flutter menggunakan sintaks pesan ICU untuk penjamakan di dalam file ARB. Paket intl menangani semua kategori penjamakan CLDR, secara otomatis menerapkan bentuk yang benar berdasarkan aturan bahasa target.

  • Gunakan sintaks {count, plural, =0{...} =1{...} other{...}} di dalam nilai string ARB.
  • Deklarasikan placeholder count dengan tipe int di metadata @key.
  • l10n.dev menghasilkan semua bentuk penjamakan yang diperlukan untuk setiap bahasa target - termasuk bahasa kompleks seperti Arab, Rusia, dan Polandia - tanpa intervensi manual.
{
  "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" }
    }
  }
}

Dukungan ARB Penuh di l10n.dev

l10n.dev dibuat khusus untuk bekerja dengan mulus dengan alur kerja ARB Flutter. Unggah file ARB sumber Anda dan terima terjemahan yang akurat dan terstruktur dengan benar:

  • Pembaruan Metadata Otomatis: @@locale diperbarui ke kode bahasa target dan @@last_modified diatur ke stempel waktu UTC saat ini secara otomatis.
  • Kontrol Terjemahan Metadata: Secara default, entri metadata @key (deskripsi, contoh, konteks) TIDAK diterjemahkan dan tetap tidak berubah, menjaga catatan penerjemah tetap utuh. Aktifkan pengaturan translateMetadata untuk menerjemahkannya bersama dengan string UI.
  • Awalan File Kustom: Pola penamaan apa pun didukung - app_en.arb, my_app_en_US.arb, strings_fr.arb, dan lainnya.
  • Format Lokal Garis Bawah: Kode lokal ARB menggunakan garis bawah (en_US, zh_CN) alih-alih tanda hubung - l10n.dev menangani ini dengan benar sehingga file yang dihasilkan langsung masuk ke proyek Flutter Anda.
  • Peka Penjamakan: Bentuk penjamakan ICU dihasilkan untuk setiap bahasa target sesuai dengan aturan CLDR, sehingga tidak diperlukan pengeditan penjamakan manual setelah terjemahan.

Otomatiskan Terjemahan dengan npm

Gunakan paket npm ai-l10n untuk menerjemahkan file ARB sumber Anda dari baris perintah atau sebagai bagian dari alur CI/CD. Instal sekali, lalu terjemahkan ke sejumlah bahasa dalam satu perintah.

# 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,ko

Integrasi ke dalam Build Flutter

Anda dapat menghubungkan ai-l10n langsung ke dalam proses build Flutter agar terjemahan selalu mutakhir sebelum aplikasi dikompilasi. Dua pendekatan umum adalah skrip package.json atau Makefile.

Melalui skrip package.json

Tambahkan skrip translate dan gunakan hook siklus hidup prebuild npm untuk menjalankannya secara otomatis sebelum setiap build. Jalankan npm run build:android (atau build:ios / build:web) dan ai-l10n akan menerjemahkan terlebih dahulu, kemudian meneruskannya ke 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"
  }
}

Melalui Makefile

Jika tim Anda menggunakan Make, deklarasikan target translate dan buat setiap target build bergantung padanya. Menjalankan make build-android (atau build-ios / build-all) akan menerjemahkan semua bahasa target sebelum memanggil 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 web

Untuk integrasi CI/CD, pembaruan inkremental, terjemahan batch di berbagai file, dan contoh alur kerja GitHub Actions, lihat Panduan Otomatisasi Lokalisasi.

Ekstensi VS Code

Ekstensi VS Code l10n.dev menghadirkan terjemahan ARB Flutter langsung ke editor Anda. Klik kanan file ARB apa pun dan terjemahkan ke bahasa target Anda tanpa meninggalkan VS Code.

Cara Kerjanya di VS Code:

  1. Buka file ARB sumber Anda (misalnya, app_en.arb) di editor.
  2. Klik kanan di editor dan pilih "Translate JSON".
  3. Pilih satu atau beberapa bahasa target (misalnya, Prancis, Jepang, Jerman).
  4. Ekstensi membuat file ARB yang dilokalkan di samping sumber Anda, dengan @@locale dan @@last_modified diperbarui secara otomatis.

Lihat Aksinya

Berikut adalah contoh langsung menerjemahkan file ARB Flutter ke bahasa Uzbek di dalam VS Code:

Flutter ARB localization in VS Code

Mulai Lokalkan Aplikasi Flutter Anda

Siap menjangkau pengguna global? Anda dapat menerjemahkan file ARB langsung di ruang kerja l10n.dev, mengotomatiskan dengan CLI npm, atau menerjemahkan langsung di dalam VS Code: