ヘルプセンター

Flutterローカリゼーション: ARBファイル、Intl、自動化

Flutterの組み込みローカリゼーションシステムは、Application Resource Bundle (ARB)ファイルとintlパッケージを使用して、あらゆる言語で完全にネイティブな体験を提供します。このガイドでは、プロジェクトのセットアップやARB形式の詳細から、言語切替、複数形の形式、l10n.devによる翻訳の自動化まで、すべてを網羅しています。

Flutterローカリゼーションとは?

Flutterローカリゼーションは、アプリを複数の言語や地域に適応させるための公式のアプローチです。翻訳された文字列を保存するためにARBファイルを使用し、型安全なDartアクセサを生成するためにflutter_genコードジェネレーターに依存しています。実行時に、Flutterはデバイスのロケールに基づいて正しいARBファイルを選択します。プログラムでロケールを切り替える際に再起動は不要です。

プロジェクトのセットアップ

Flutterのローカリゼーションパイプラインは、pubspec.yamlとl10n.yamlという2つの設定ファイルによって駆動されます。pubspec.yamlでコード生成を有効にし、FlutterにARBディレクトリを指定してください。

1. pubspec.yamlの更新

flutter_localizationsとintlを依存関係に追加し、generateフラグを有効にすることで、FlutterがARBファイルからDartローカリゼーションクラスを自動生成するようにします。

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

flutter:
  generate: true

2. l10n.yamlの作成

プロジェクトのルートにl10n.yamlファイルを配置し、ARBディレクトリ、テンプレートファイル、生成される出力ファイル名を構成します。

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

ARBファイル形式

ARB (Application Resource Bundle) は、Flutterのi18n用に特別に設計されたJSONベースの形式です。各キーは翻訳可能な文字列にマッピングされ、オプションのメタデータキー(@で始まる)には、翻訳者向けの記述、プレースホルダーの定義、コンテキストが含まれます。

  • @@locale: ファイルのロケールを宣言します(例: "en", "fr", "zh_CN")。l10n.devはこれをターゲット言語コードに自動的に更新します。
  • @@last_modified: 最終更新のタイムスタンプです。l10n.devは翻訳ファイルを生成する際、これを現在のUTCタイムスタンプに自動設定します。
  • @keyメタデータ: description、example、placeholdersなどのメタデータエントリは、デフォルトでは翻訳されません。翻訳者のコンテキストを維持するために変更されません。これらも翻訳したい場合は、translateMetadata設定を有効にしてください。
  • プレースホルダーとICUメッセージ: 文字列には、名前付きプレースホルダー ({name}) や複数形の形式および選択のためのICUメッセージ構文を含めることができ、これらはすべて翻訳中に正しく保持されます。

ソースARBファイル (英語)

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

翻訳済みARBファイル (フランス語)

翻訳後、UI文字列はローカライズされますが、メタデータの構造はそのまま維持されます。l10n.devは@@localeと@@last_modifiedを自動的に更新します。

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

ファイル命名規則

ARBファイルは、プレフィックス(デフォルトではapp_)の後にロケールコードと.arb拡張子が続く単純な命名パターンに従います。Flutterとl10n.devは、言語コードと地域コードを区切るためにアンダースコアを使用します。

ARBファイルはハイフンではなくアンダースコアを使用します。app_en-US.arbやapp_zh-CN.arbではなく、app_en_US.arbや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

プロジェクト構造

すべてのARBファイルをlib/内の専用のl10nフォルダーに整理します。Flutterのコードジェネレーターは、l10n.yamlのarb-dir設定に基づいてそれらを自動的に取得し、すぐに使用できるDartクラスを出力します。

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

初期化

localizationsDelegatesとsupportedLocalesを提供することで、生成されたDartローカリゼーションクラスをMaterialAppと接続します。これにより、Flutterはデバイスのロケールに合わせて正しいARBデータを解決します。

MaterialAppのセットアップ

生成されたAppLocalizations.delegateと3つのFlutter SDKデリゲートの計4つの必要なデリゲートを渡し、アプリがサポートするすべてのロケールをリストアップします。翻訳された文字列にアクセスするには、ウィジェットツリーのどこからでもAppLocalizations.of(context)!を使用してください。

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では、MaterialAppのlocaleプロパティを更新することで、実行時にアプリのロケールを切り替えることができます。一般的なパターンは、StatefulWidgetまたは状態管理ソリューションにLocaleを保持し、それを変更するためのコールバックを公開することです。ウィジェットツリーは新しいロケールで自動的に再構築されます。

// 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はARBファイル内の複数形の形式にICUメッセージ構文を使用します。intlパッケージはすべてのCLDR複数形カテゴリを処理し、ターゲット言語のルールに基づいて正しい形式を自動的に適用します。

  • ARB文字列値内で {count, plural, =0{...} =1{...} other{...}} 構文を使用します。
  • @keyメタデータでcountプレースホルダーをint型として宣言します。
  • l10n.devは、アラビア語、ロシア語、ポーランド語などの複雑な言語を含む、各ターゲット言語に必要なすべての複数形の形式を手動介入なしで生成します。
{
  "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での完全なARBサポート

l10n.devは、FlutterのARBワークフローとシームレスに連携するように構築されています。ソースARBファイルをアップロードすると、正確で適切に構造化された翻訳が返されます。

  • メタデータの自動更新: @@localeはターゲット言語コードに更新され、@@last_modifiedは現在のUTCタイムスタンプに自動的に設定されます。
  • メタデータ翻訳の制御: デフォルトでは、@keyメタデータエントリ(description、example、context)は翻訳されず、翻訳者のメモを維持するために変更されません。UI文字列と一緒に翻訳するには、translateMetadata設定を有効にしてください。
  • カスタムファイルプレフィックス: app_en.arb、my_app_en_US.arb、strings_fr.arbなど、あらゆる命名パターンがサポートされています。
  • アンダースコアロケール形式: ARBロケールコードはハイフンの代わりにアンダースコア(en_US, zh_CN)を使用します。l10n.devはこれを正しく処理するため、生成されたファイルはそのままFlutterプロジェクトに組み込めます。
  • 複数形の形式対応: ICU複数形の形式はCLDRルールに従ってすべてのターゲット言語に対して生成されるため、翻訳後に手動で複数形を編集する必要はありません。

npmによる翻訳の自動化

ai-l10n npmパッケージを使用して、コマンドラインから、またはCI/CDパイプラインの一部としてソースARBファイルを翻訳します。一度インストールすれば、単一のコマンドで任意の数の言語に翻訳できます。

# 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

Flutterビルドへの統合

ai-l10nをFlutterのビルドプロセスに直接組み込むことで、アプリがコンパイルされる前に常に翻訳が最新の状態になるようにできます。一般的なアプローチとして、package.jsonスクリプトまたはMakefileを使用する方法があります。

package.jsonスクリプト経由

translateスクリプトを追加し、npmのprebuildライフサイクルフックを使用して、すべてのビルドの前に自動的に実行します。npm run build:android(またはbuild:ios / build:web)を実行すると、ai-l10nが最初に翻訳を行い、その後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"
  }
}

Makefile経由

チームでMakeを使用している場合は、translateターゲットを宣言し、各ビルドターゲットをそれに依存させます。make build-android(またはbuild-ios / build-all)を実行すると、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

CI/CD統合、増分更新、複数ファイルにわたる一括翻訳、GitHubアクションのワークフロー例については、以下を参照してください。ローカリゼーション自動化ガイド

VS Code拡張機能

l10n.devのVS Code拡張機能を使用すると、エディタ内で直接Flutter ARB翻訳を行えます。ARBファイルを右クリックして、VS Codeを離れることなくターゲット言語に翻訳できます。

VS Codeでの動作:

  1. エディタでソースARBファイル(例: app_en.arb)を開きます。
  2. エディタ内で右クリックし、「Translate JSON」を選択します。
  3. 1つ以上のターゲット言語(例: フランス語、日本語、ドイツ語)を選択します。
  4. 拡張機能がソースの横にローカライズされたARBファイルを作成し、@@localeと@@last_modifiedを自動的に更新します。

実際の動作を見る

VS Code内でFlutter ARBファイルをウズベク語に翻訳するライブデモです:

Flutter ARB localization in VS Code

Flutterアプリのローカリゼーションを開始

世界中のユーザーにリーチする準備はできましたか?l10n.devワークスペースで直接ARBファイルを翻訳するか、npm CLIで自動化するか、VS Code内で翻訳することができます。