Search code examples
flutterinternationalization

Why is Flutter not generating the internationalization files?


I'm trying to follow the internationalization documentation in https://flutter.dev/docs/development/accessibility-and-localization/internationalization#dart-tools and https://docs.google.com/document/d/10e0saTfAv32OZLRmONy866vnaw0I2jwL8zukykpgWBc/edit#heading=h.upcu5w85cvc2 but it's not generating any files.

Basically it says to make these mods to the pub spec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.17.0-nullsafety.2
flutter:
  generate: true

Then create a <project-root>/l10n.yaml file containing:

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

And finally to create the app_en.arb with something like this:

{
  "@@locale": "en",

  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "The conventional newborn programmer greeting"
  }
}

And from there the guides say that a flutter_gen/gen_l10n/app_localizations.dart file will be automatically generated.

Except that nothing happens. I'm working in Android Studio and did a pub get, and tried a flutter clean and flutter build ios and everything else I can't think of but nothing is building that file.

Any ideas?


Solution

  • Ok. done some more digging and I've solved it. Basically the Flutter documentation is slightly out of date.

    The files generated generated by flutter_localizations (by running flutter gen-l10n) are being generated, but they're in <project_dir>.dart_tools/flutter_gen/gen_l10n. Unless specified otherwise in the l10n.yaml, the generator creates a synthetic package that is automatically available to the project so there is no need for any further changes in pubspec.yaml.

    Secondly, your main.dart has to look like this:

    import 'package:flutter/material.dart';
    import 'package:flutter_gen/gen_l10n/app_localizations.dart';
    
    class MyApp extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          localizationsDelegates: AppLocalizations.localizationsDelegates,
          supportedLocales: AppLocalizations.supportedLocales,
          title: 'My app',
          home: ... ,
        );
      }
    }
    
    

    Two things here:

    1. The importing of the app_localizations.dart generated file (which the docs do mention but perhaps not explain well) and ...
    2. Changing the localizationsDelegates and supportedLocales. You don't need to list all the delegates and locales mentioned in the docs as the generated localisation files automatically include them. Just switch to the two properties of AppLocalizations.

    PS

    After writing the above I attempted to internationalise the app's title:

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

    Epic fail - The reason is that at the time it goes to resolve the title, the delegates and locales have not yet been set so what comes back from AppLocalizations.of(context) is a null. Instead you need to change to the onGeneratedTitle like this:

      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          localizationsDelegates: AppLocalizations.localizationsDelegates,
          supportedLocales: AppLocalizations.supportedLocales,
          onGenerateTitle: (context) => AppLocalizations.of(context).applicationTitle,
          home: ... ,
        );
      }
    ```.  
    
    `onGeneratedTitle` is called after the widget is setup which means localisation is available.