Flutterの組み込みローカリゼーションシステムは、Application Resource Bundle (ARB)ファイルとintlパッケージを使用して、あらゆる言語で完全にネイティブな体験を提供します。このガイドでは、プロジェクトのセットアップやARB形式の詳細から、言語切替、複数形の形式、l10n.devによる翻訳の自動化まで、すべてを網羅しています。
Flutterローカリゼーションは、アプリを複数の言語や地域に適応させるための公式のアプローチです。翻訳された文字列を保存するためにARBファイルを使用し、型安全なDartアクセサを生成するためにflutter_genコードジェネレーターに依存しています。実行時に、Flutterはデバイスのロケールに基づいて正しいARBファイルを選択します。プログラムでロケールを切り替える際に再起動は不要です。
Flutterのローカリゼーションパイプラインは、pubspec.yamlとl10n.yamlという2つの設定ファイルによって駆動されます。pubspec.yamlでコード生成を有効にし、FlutterにARBディレクトリを指定してください。
flutter_localizationsとintlを依存関係に追加し、generateフラグを有効にすることで、FlutterがARBファイルからDartローカリゼーションクラスを自動生成するようにします。
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
flutter:
generate: trueプロジェクトのルートにl10n.yamlファイルを配置し、ARBディレクトリ、テンプレートファイル、生成される出力ファイル名を構成します。
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dartARB (Application Resource Bundle) は、Flutterのi18n用に特別に設計されたJSONベースの形式です。各キーは翻訳可能な文字列にマッピングされ、オプションのメタデータキー(@で始まる)には、翻訳者向けの記述、プレースホルダーの定義、コンテキストが含まれます。
{
"@@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"
}
}
}
}翻訳後、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は、言語コードと地域コードを区切るためにアンダースコアを使用します。
# 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.dartlocalizationsDelegatesとsupportedLocalesを提供することで、生成されたDartローカリゼーションクラスをMaterialAppと接続します。これにより、Flutterはデバイスのロケールに合わせて正しいARBデータを解決します。
生成された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複数形カテゴリを処理し、ターゲット言語のルールに基づいて正しい形式を自動的に適用します。
{
"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は、FlutterのARBワークフローとシームレスに連携するように構築されています。ソースARBファイルをアップロードすると、正確で適切に構造化された翻訳が返されます。
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,koai-l10nをFlutterのビルドプロセスに直接組み込むことで、アプリがコンパイルされる前に常に翻訳が最新の状態になるようにできます。一般的なアプローチとして、package.jsonスクリプトまたはMakefileを使用する方法があります。
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"
}
}チームで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 webCI/CD統合、増分更新、複数ファイルにわたる一括翻訳、GitHubアクションのワークフロー例については、以下を参照してください。ローカリゼーション自動化ガイド
l10n.devのVS Code拡張機能を使用すると、エディタ内で直接Flutter ARB翻訳を行えます。ARBファイルを右クリックして、VS Codeを離れることなくターゲット言語に翻訳できます。
VS Code内でFlutter ARBファイルをウズベク語に翻訳するライブデモです:

世界中のユーザーにリーチする準備はできましたか?l10n.devワークスペースで直接ARBファイルを翻訳するか、npm CLIで自動化するか、VS Code内で翻訳することができます。
l10n.devを使用してFlutterアプリをローカライズしていただきありがとうございます!🚀
このガイドが役に立った場合は、世界中のユーザーにリーチする必要がある他のFlutter開発者と共有してください。
Flutterアプリをより包括的で世界に対応したものにしていきましょう。