0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Flutter】Flutterマルチモジュール での多言語(l10n)設計ガイド

Last updated at Posted at 2025-08-18

結論:

  • 各 Feature モジュールごとに gen_l10n を独立運用(ARBと生成コードをモジュール内完結)。

  • App(シェル)側で delegates と supportedLocales を集約。

  • Domain/Data 層は文言を持たない(エラーはコードで表す、文言は Presentation 層でローカライズ)。


全体像(責務分離)


ディレクトリ例(melos想定)

packages/
  app/
  core/locale/              # (任意)Locale永続化の共通部品
  features/
    weather/
      lib/
        l10n/
          weather_en.arb
          weather_ja.arb
          weather_localizations.dart   # synthetic-package:false時の出力
        src/
          public/   # 外部に見せる最小API(routes/di/l10nゲッター等)
          internal/ # 実装詳細(UI, repo等)
      l10n.yaml
      pubspec.yaml
    auth/
      ...

ポイント

  • 各 Feature 配下に l10n/ を置く(モジュール独立)。

  • l10n.yaml の output-class を モジュール固有名 に(例:WeatherLocalizations)。

  • 生成物の公開は必要最小限に(barrel weather.dart から show で制御)。


l10n.yaml(Feature側:weather の例)

arb-dir: lib/l10n
template-arb-file: weather_en.arb
output-localization-file: weather_localizations.dart
output-class: WeatherLocalizations
synthetic-package: false
use-deferred-loading: false
preferred-supported-locales:
  - ja
  - en
# 任意: 出力先を固定したい場合
# output-dir: lib/l10n/gen

ARBキー命名(衝突回避の鉄則)

  • 必ずモジュール接頭辞を付ける:weather_ / auth_ / settings_ …

例:weather_appTitle, weather_errorTimeout, weather_tempHighLow など。

lib/l10n/weather_en.arb


{
  "@@locale": "en",
  "weather_appTitle": "PoyoPoyo Weather",
  "weather_settings": "Settings",
  "weather_theme_setting": "🌗 Theme Setting",
  "weather_language_setting": "🌐 Language Setting",
  ...
}

lib/l10n/weather_ja.arb

{
  "@@locale": "ja",
  "weather_appTitle": "ポヨポヨ 天気",
  "weather_settings": "設定",
  "weather_theme_setting": "🌗 テーマ設定",
  "weather_language_setting": "🌐 言語設定",
  ...
}

Feature内での利用

  final loc = WeatherLocalizations.of(context)!;
  loc.weather_appTitle;

App(シェル)側での集約

Locale切り替えと永続化(SharedPreferences × Riverpod例)

locale_repository.dart

locale_repository_impl.dart

locale_provider

公開APIの最小化(情報隠蔽)

  • lib/src/internal/ に実装、lib/src/public/ に“壳”API(routes/di/l10nゲッター)。

  • lib/feature_xxx.dart を 唯一の公開barrel にし、export show で必要最小限を露出。

  • Lintで implementation_imports: true を有効化し、package:meta の @internal を活用。


CI / 開発フロー(melos)

melos.yaml にスクリプトを用意し、全Featureのgen_l10nを一括:

scripts:
  gen-l10n:
    run: melos exec -- "flutter gen_l10n"
    description: "Generate localizations in all Flutter packages"

PRチェック例

  • gen_l10n の未実行防止(差分に生成物あり/なしのチェック)。

  • ARB スキーマ検査(キー重複・未翻訳・不要キー検出)。


よくあるハマりどころ

オプション名の誤記:

  • template_arbs × → template-arb-file ○

  • preferred_locales × → preferred-supported-locales ○

生成先の誤解:

  • synthetic-package: false の場合は 同パッケージ配下に直接出力。output-dir 指定で固定化も可。

ARBキー衝突:

  • 接頭辞で防止(weather_ など)。

Domainに文言を持ち込む:

  • NG。エラーは Failure/Code で返し、UI層で文言化する。

チェックリスト

  • 各Featureに l10n/ と l10n.yaml を配置、output-class は固有名

  • ARBキーは feature_ プレフィックスで衝突回避

  • Domain/Dataは文言を持たず、Presentationでローカライズ

  • Appで delegates / supportedLocales を集約

  • Localeは状態管理+永続化(Repository化)

  • 公開APIはbarrelから最小限 export show、内部は src/internal

  • Lint(implementation_imports)と @internal で“越権import”を抑止

  • CIで gen_l10n と ARB検査を実行

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?