Pusat Bantuan

Lokalisasi Flutter: File ARB, Intl & Otomatisasi

Sistem lokalisasi bawaan Flutter menggunakan file Application Resource Bundle (ARB) dan paket intl untuk memberikan pengalaman asli sepenuhnya dalam bahasa apa pun. Panduan ini mencakup segalanya 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. Ini mengandalkan file ARB untuk menyimpan string yang diterjemahkan dan generator kode flutter_gen untuk menghasilkan aksesor Dart yang aman secara tipe. Saat runtime, Flutter memilih file ARB yang benar 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 templat, 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 @) membawa 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 entri tersebut diterjemahkan.
  • Placeholder dan pesan ICU: String dapat berisi placeholder bernama ({name}) dan sintaks pesan ICU untuk penjamakan dan pemilihan - 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 dilokalisasi 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 mudah: awalan (secara default 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 mengeluarkan 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 benar untuk lokal perangkat.

Pengaturan MaterialApp

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

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 untuk mengganti lokal aplikasi saat runtime dengan memperbarui properti locale pada MaterialApp. Pola umum adalah menyimpan Locale di 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 yang 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 string UI.
  • Awalan File Kustom: Pola penamaan apa pun didukung - app_en.arb, my_app_en_US.arb, strings_fr.arb, dan banyak lagi.
  • 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 aturan CLDR, sehingga tidak diperlukan pengeditan penjamakan manual setelah penerjemahan.

Otomatisasi 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 Anda sehingga 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, lalu menyerahkannya 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 menjalankan 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 beberapa 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 dilokalisasi 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 Melokalisasi Aplikasi Flutter Anda

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