GDPR準拠組織

ISO 27001認証取得組織

SOC II準拠組織

Flutterのローカライズ:ARBファイル、intl、gen-l10nを解説

Flutterのローカライズでは、アプリのメッセージとインターフェースを各ロケールに合わせて最適化します。組み込みのワークフローでは、flutter_localizationsがフレームワークのウィジェットをローカライズし、ARBリソースとgen-l10nがアプリのAppLocalizations APIを生成します。intlは言語に依存するメッセージと書式設定を支援します。

デモを予約

デモを予約

小さなARBサンプルと、ビルドに必要なチェック項目をご用意ください

無料トライアルを開始

無料トライアルを開始

15日間無料、クレジットカード不要

対象言語別の翻訳の進捗を示すSmartcatのソフトウェアローカライズプロジェクト

世界最大級の企業80社以上がSmartcatを選んでいます

flutter_localizationsとgen-l10nをセットアップする

このガイドでは、英語とスペイン語の小さな例をセットアップし、メッセージのメタデータを説明し、一般的なパッケージのアプローチを比較します。また、翻訳プラットフォームをFlutterプロジェクトに接続する前に検証すべき点も紹介します。

ローカライズのジェネレーターは1つに絞り、その入力先と出力先を明示します。以下の例は、独自のSDK制約と通常のプロジェクト設定を持つ既存のFlutterアプリを前提としています。

関連するエントリをpubspec.yamlにマージします。dependenciesセクションやflutterセクションを重複させないでください:

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

flutter:
  generate: true

flutter pub getで依存関係を解決します。intl: anyのエントリは公式のセットアップ手順に従ったもので、Flutter SDKと互換性のあるバージョンを依存関係の解決時に選択できます。アプリのロックファイルと通常の依存関係レビュープロセスは維持してください。

プロジェクトのルートにl10n.yamlを作成します:

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

SDK固有のセットアップには、最新のFlutter国際化ガイドを参照してください。現在のワークフローでは、生成されたローカライズファイルはアプリのソースツリーに配置します。この例ではlib/l10nからインポートしています。古い合成パッケージpackage:flutter_genのインポートを新しいセットアップにコピーしないでください。詳しくは生成ソースの移行に関する注記をご覧ください。

文脈と型付きプレースホルダーを含むARBファイルを作成する

ARBファイルは、メッセージと任意のメタデータを含むJSONベースのリソースバンドルです。メッセージキーは安定させ、メッセージは完全な形で書き、メタデータでテキストの使われ方を説明します。

lib/l10n/app_en.arbを作成します:

{
  "@@locale": "en",
  "appTitle": "Reading room",
  "@appTitle": {
    "description": "Title of the sample reading application"
  },
  "welcomeName": "Welcome, {name}",
  "@welcomeName": {
    "description": "Greeting on the home screen",
    "placeholders": {
      "name": {"type": "String", "example": "Sam"}
    }
  },
  "savedBooks": "{count, plural, =0{No saved books} one{1 saved book} other{{count} saved books}}",
  "@savedBooks": {
    "description": "Number of books saved to the user's library",
    "placeholders": {
      "count": {"type": "int"}
    }
  },
  "readingState": "{state, select, active{Reading now} paused{Reading paused} other{Ready to read}}",
  "@readingState": {
    "description": "Reading status; state is active, paused or another value",
    "placeholders": {
      "state": {"type": "String"}
    }
  }
}

lib/l10n/app_es.arbを作成します:

{
  "@@locale": "es",
  "appTitle": "Sala de lectura",
  "welcomeName": "Te damos la bienvenida, {name}",
  "savedBooks": "{count, plural, =0{No hay libros guardados} one{1 libro guardado} other{{count} libros guardados}}",
  "readingState": "{state, select, active{Leyendo ahora} paused{Lectura en pausa} other{Todo listo para leer}}"
}

テンプレートには、ジェネレーターが使用するプレースホルダーのメタデータが含まれます。ローカライズファイルでは、ユーザー向けの文言を変更しつつ、メッセージキー、プレースホルダー名、select識別子を保持します。これらのスペイン語の例は仕組みを示すためのもので、本番の文言は実際の製品の文脈でネイティブレビューを受ける必要があります。

リソースを追加または変更したらflutter gen-l10nを実行します。ジェネレーターのエラーは対処すべきリソースの問題として扱い、ファイルをリリースに組み込む前に解決してください。

生成されたメッセージをMaterialAppに接続する

生成されたデリゲートとサポート対象ロケールを登録し、アプリのウィジェットより下のコンテキストからローカライズされたメッセージを読み取ります。

生成後、次の例をlib/main.dartに記述します:

import 'package:flutter/material.dart';
import 'l10n/app_localizations.dart';

void main() => runApp(const ReadingApp());

class ReadingApp extends StatelessWidget {
  const ReadingApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: const ReadingHome(),
    );
  }
}

class ReadingHome extends StatelessWidget {
  const ReadingHome({super.key});

  @override
  Widget build(BuildContext context) {
    final messages = AppLocalizations.of(context)!;
    return Scaffold(
      appBar: AppBar(title: Text(messages.appTitle)),
      body: Padding(
        padding: const EdgeInsetsDirectional.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(messages.welcomeName('Sam')),
            Text(messages.savedBooks(3)),
            Text(messages.readingState('active')),
          ],
        ),
      ),
    );
  }
}
ReadingHome は、 MaterialAppが提供するローカライズにアクセスできます。外側のウィジェットのコンテキストから AppLocalizations を要求すると、そのウィジェット自身が作成したプロバイダーより上を探すことになります。 Localizations APIのドキュメント では、ローカライズされたリソースを子孫ウィジェットで利用できるようにする仕組みが説明されています。

生成されたAPIでは、単純なメッセージと引数付きメッセージの違いがコード上で明確になります。appTitleは値としてアクセスし、welcomeName、savedBooks、readingStateはメッセージの組み立てに必要な値を受け取ります。

複数形とselectメッセージを意図的に扱う

複数形メッセージは、数量と対象ロケールの文法に応じて文言を選びます。selectメッセージは、アプリが渡す識別子に応じて分岐を選びます。各分岐で表示されるテキストを翻訳しつつ、構文と識別子は保持してください。

複数形

この例では、=0が空の状態用の文を明示的に提供しています。oneとotherの分岐はサンプル言語で使われる形をカバーするもので、あらゆる対象ロケールに通用するテンプレートではありません。言語が必要とする形とアプリが生成し得る値をレビュアーが把握できるよう、十分な文脈を提供してください。

selectメッセージ

activeやpausedなどの値はプログラムの識別子です。これらを翻訳すると、値を渡すコードとリソースのつながりが切れてしまいます。otherの分岐は、名前付きの分岐に一致しない値に対するフォールバックになります。

完全なメッセージ

翻訳された動詞、数値、翻訳された名詞といった断片を連結するのは避けてください。完全なメッセージにすれば、対象言語に合わせて語順を調整できます。値、想定される範囲、画面の文脈をブリーフで説明し、レビュアーがユーザーの目に触れる形で文を評価できるようにしましょう。

Flutterのローカライズパッケージを比較する

パッケージは、リソース形式、アプリのアーキテクチャ、保守の要件に基づいて選びます。以下のパッケージはそれぞれ異なる規約を持ちます。同じメッセージに複数のジェネレーターを採用すると、不要なあいまいさが生じます。

アプローチ主なリソースコード生成複数形の扱い適しているケース
組み込みのgen-l10nARB型付きのDartアクセサーを生成ICU形式のメッセージ構文Flutter公式のリソースワークフローを使いたい場合
easy_localizationデフォルトはJSON、追加のローダーも利用可能任意の生成ツールパッケージの複数形APIとロケールに応じたルールアセット読み込みとロケール管理の規約が好みに合う場合
GetXの翻訳機能ドキュメント記載の基本ワークフローではロケールをキーとするマップ基本的なマップAPIでは不要trPluralは単数・複数のキーを使用。より複雑な文法は別途評価が必要アプリですでにGetXを使用しており、その翻訳モデルが要件に合う場合

選定前に、最新のeasy_localizationのドキュメントとGetXのドキュメントを確認してください。フォールバックの動作、パラメーター、複数形のカテゴリー、抽出ワークフローを実際のメッセージでテストしましょう。英語の文字列で使いやすいAPIだからといって、リリース予定のすべての言語に対応できるとは限りません。

intlは、翻訳管理プラットフォームと競合するものではありません。ローカライズのワークフローで使われる国際化ユーティリティを提供します。gen-l10nはARBリソースからアプリのアクセサーを生成します。別のintl_utilsパッケージもローカライズ用のコードを生成しますが、2026年10月30日の確認時点でパッケージページに開発終了と表示されていました。新しいプロジェクトで採用する前に、保守状況を確認してください。

ロケールの切り替え、RTL、テキストの伸長をテストする

リソースの正しさと、翻訳されたテキストがインターフェース上でどう振る舞うかの両方をテストします。JSONの解析やコード生成が成功しても、画面がわかりやすく使いやすいことの証明にはなりません。

ロケールの切り替え

開発時の簡単な確認では、MaterialApp.localeをconst Locale('es')などのサポート対象の値に設定します。本番の言語セレクターでは、選択されたロケールをアプリの状態に保持し、製品要件に従って設定を永続化し、システム言語に従うオプションも用意します。保存された設定は、現在のアプリバージョンが実際にサポートするロケールと照合して検証してください。

右から左へのレイアウト

読む方向に従うべき要素には、方向対応のレイアウトAPIを使用します。実際の右から左へ書くロケールで、余白、配置、ナビゲーションの手がかり、方向が混在するコンテンツを確認してください。すべてのアイコンを反転すべきとは限りません。方向を示すナビゲーション矢印とブランドのシンボルでは意味が異なります。

テキストの伸長

長い翻訳と大きな文字サイズをテストします。ボタン、タブ、ダイアログ、空の状態、エラー、幅の狭いレイアウトを確認してください。長い名前や数値などの動的な値も含め、ユーザーが実際に目にするメッセージでレイアウトを確認しましょう。

実用的なテストマトリクスを使用します:

チェック項目例
リソースの網羅性必要なテンプレートキーすべてに、意図したローカライズ値またはフォールバックがある
メッセージの引数プレースホルダーの名前と型が生成されたメソッドと互換性を保っている
数量に応じた動作0、1、および対象言語の追加の形を確認できる値
selectの動作既知の状態に加え、otherに到達する想定外の値
ロケールの動作システム言語、明示的な選択、再起動、サポート外の設定
レイアウト伸長したテキスト、大きなフォント設定、右から左へのコンテンツ
意味重要なユーザージャーニーのネイティブレビュー

プロセスの言語面については、ローカライズテストのワークフローを活用してください。言語面の承認と機能テストの結果は、リリースの根拠として別々に確認できるようにしておきます。

Flutter Webのローカライズと検索での発見性は別々に計画する

Flutter Webではローカライズされたアプリリソースを使用できますが、インターフェースをローカライズしても、SEOに対応した多言語Webサイトが自動的にできるわけではありません。言語の選択、ルーティング、メタデータ、コンテンツの発見性は、引き続きアーキテクチャ上の判断事項です。

FlutterのWeb FAQでは、アプリケーション体験に重点を置いていることが説明されており、静的でテキスト中心のWebコンテンツにはドキュメント指向のアプローチが推奨されています。マーケティング、ヘルプ、編集記事のページがオーガニック検索で成果を上げる必要がある場合は、HTMLベースの別ページを検討してください。

アプリとこれらの公開ページの間で用語をそろえてください。2つの画面が異なるレンダリング方式を使っていても、検索から訪れたユーザーがローカライズされたランディングページからアプリに移ったときに、機能名を認識できるようにします。

拡大する前にARB翻訳ワークフローを検証する

ARBは単なるテキスト値のファイルではなく、構造化されたアプリリソースとして扱ってください。翻訳の引き渡しでは、キー、メタデータ、プレースホルダー、メッセージ構文を保持し、生成とアプリのテストに合格するファイルを返す必要があります。

Smartcatのドキュメントに記載されたソフトウェアプロジェクト形式には、JSON、YAML、Android XML、iOS .strings、LocJSONのインポートが含まれます。本ガイドで確認したドキュメントでは、ARBのネイティブサポートや、テスト済みのARBからJSONへの変換ワークフローは確認されていません。ファイル拡張子を変えるだけで互換性が証明されるとは考えないでください。ソフトウェアプロジェクトのドキュメントをご覧ください。

以下はテスト済みのコネクター手順ではなく、実装チームと進める検証手順の提案としてご活用ください:

  1. 代表的なサンプルを選ぶ

    単純な文字列、メタデータ、型付きプレースホルダー、複数形、selectを含む小さなARBサンプルを選びます。

  2. インポートとエクスポートを確認する

    @メタデータとICUメッセージの扱いを含め、サポートされるインポート/エクスポート方法を製品チームに確認します。

  3. 言語アセットと文脈を提供する

    用語集、必要に応じて翻訳メモリ、各メッセージのわかりやすい文脈を提供します。

  4. 構造を保護しながら翻訳する

    プログラムの識別子と構造を保護しながら、ユーザー向けテキストを翻訳・レビューします。

  5. 比較して戻す

    返されたリソースをソースの仕様と比較し、想定どおりのプロジェクトパスに戻します。

  6. 生成してテストする

    プロジェクトで固定されたSDK環境で、flutter gen-l10n、静的解析、関連テストを実行します。

  7. レビューして記録する

    ローカライズされたインターフェースをレビューし、承認されたソースのバージョンを記録します。

リポジトリの同期を自動化するのは、この往復が成功してからにしてください。ソースの変更を誰が扱うか、レビューのステータスをどう無効化するか、生成された成果物をどう管理するかを定義します。ARBリソースはアプリのワークフローにおける信頼できる唯一の情報源として、バージョン管理下に置いてください。

Flutterの翻訳ワークフローを見直す

よくある不具合と最初に確認すべき点

症状最初の確認点
生成されたインポートが見つからない生成が正常に完了し、インポートが設定済みの出力パスと一致しているか
AppLocalizations.of(context)が利用できないコンテキストがアプリのローカライズプロバイダーより下にあるか
メッセージのメソッドに想定外の引数があるテンプレートのプレースホルダーメタデータと生成されたAPI
selectが常にフォールバックを表示するアプリの識別子がリソースの分岐と完全に一致しているか
ロケールが見つからないリソースファイル、サポート対象ロケール、ロケール解決の設定
エクスポート後に翻訳が壊れるキー、JSONの妥当性、メタデータ、ICU構文が往復後も保たれているか

生成されたDartコードを手作業で編集するのではなく、最初に壊れた箇所の仕様を修正してください。生成コードは再生成されるため、そこで手動修正しても次にリソースが変わったときに消えてしまう可能性が高くなります。

よくある質問

FlutterのARBファイルとは何ですか?

Application Resource Bundleは、ローカライズされたメッセージと任意のメタデータを含むJSONベースのファイルです。Flutterのgen-l10nワークフローは、ARBリソースからDartのローカライズAPIを生成します。メタデータでメッセージとプレースホルダーを説明でき、開発者と翻訳者にとって各キーの仕様がより明確になります。

gen-l10nとintl_utilsの違いは何ですか?

どちらもARBリソースからローカライズ用のコードを生成しますが、設定と出力の規約が異なる別々のツールです。gen-l10nはFlutterの組み込みワークフローの一部です。本ガイドの確認時点で、intl_utilsのパッケージページには開発終了と表示されていたため、新たな実装に採用する前に保守状況を確認してください。

ARBファイルはどのように翻訳すればよいですか?

安定したキー、プレースホルダーの識別子、メタデータ、必要なメッセージ構造を保持しながら、ユーザー向けのメッセージを翻訳します。これらの要件に対応したワークフローを使用し、返されたファイルで生成とアプリのテストを実行してください。ネイティブレビューでは、構造上の妥当性に加えて意味と文脈も評価する必要があります。

SmartcatはARBのプレースホルダーと複数形に対応していますか?

ここで確認したソフトウェアプロジェクトのドキュメントでは、ARBのネイティブサポートや、ARBのすべての機能を保持するテスト済みの変換方法は確認されていません。導入前に製品チームとインポート/エクスポートの方法を確認し、代表的なサンプルで往復の検証を行ってください。汎用的なJSONサポートだけでは、ARBとの互換性は証明されません。

FlutterのローカライズはWebでも機能しますか?

Flutter Webアプリでも、ローカライズされたリソースとロケールの選択を利用できます。検索での発見性は別の課題であり、公開するマーケティングやヘルプのコンテンツにはHTMLベースのアーキテクチャが適している場合があります。モバイルのローカライズ設定でWebのSEOまで完了すると考えず、ご自身のWeb体験でルーティング、言語選択、メタデータをテストしてください。

答えが見つかりませんか? ローカライズの専門家に相談する

翻訳の引き渡しを、リソースの仕様と同じくらい確実なものに

小さなARBサンプルと、ビルドに必要なチェック項目をお持ちください。すべての言語とリリースに拡大する前に、ワークフローを確認しましょう。