Flutter & i18n in a nutshell

During my first steps in develop some Flutter apps I came across - as always - the requirement for adding internationalization. In Flutter it's a three steps way to go to have i18n in your widgets. First of all you have to create a class to present your strings to the widget, then you have to run a command on the command line to generate a file which contains the basis of the translation which you then can translate yourself and finally you need to run another command to have a class generate which basically resolve the right translation for the requested string ... and don't forget to add some dependencies to the pubspec.yaml :).

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  flutter_cupertino_localizations: ^1.0.1
  intl: ^0.15.8
  ...

dev_dependencies:
  flutter_test:
    sdk: flutter
  intl_translation: ^0.17.1
  ...

Here it is in a nutshell:

  1. Create your app localization class
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'i18n/messages_all.dart';

class AppLocalizations {
  static Future<AppLocalizations> load(Locale locale) {
    final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
    final String localeName = Intl.canonicalizedLocale(name);

    return initializeMessages(localeName).then((_) {
      Intl.defaultLocale = localeName;
      return AppLocalizations();
    });
  }

  static AppLocalizations of(BuildContext context) {
    return Localizations.of<AppLocalizations>(context, AppLocalizations);
  }

  String get title {
    return Intl.message(
      'Hello World',
      name: 'title',
      desc: 'Title for the Demo application',
    );
  }
}

class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
  const AppLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'de'].contains(locale.languageCode);

  @override
  Future<AppLocalizations> load(Locale locale) => AppLocalizations.load(locale);

  @override
  bool shouldReload(AppLocalizationsDelegate old) => false;
}

** Sample code taken from https://proandroiddev.com/flutter-localization-step-by-step-30f95d06018d

Change the MaterialApp creation

class MyApp extends StatefulWidget {
  @override
  State<MyApp> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        const AppLocalizationsDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('en', ''),
        const Locale('de', ''),
      ],
      title: 'MyApp',
      home: MyWidget()
    );
  }

}

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      appBar: AppBar(
        title: Text(AppLocalizations.of(context).title()),
      ),
      body: Center(
        child: Text('Hello World'),
      ),
    );
  }

}```

2. Run the command on the command line

flutter pub pub run intl_translation:extract_to_arb --output-dir=lib/i18n lib/localizations.dart

As you can see I've put my above localization class code to a file called localizations.dart and I want to have the generated stuff in the i18n dir.

3. Run the command the generates the the dart class to retrieve the translated elements

flutter pub pub run intl_translation:generate_from_arb --output-dir=lib/i18n --no-use-deferred-loading lib/localizations.dart lib/i18n/intl_*.arb

See the part with intl_*, which are files with names like intl_en.arb and intl_de.arb which contain the same content als the in step 2 generated file intl_messages.arb

That's it, now you're good to go and you can use these translations in your code like

Text(AppLocalizations.of(context).title)

Some usefule links:
https://proandroiddev.com/flutter-localization-step-by-step-30f95d06018d
https://flutter.dev/docs/development/accessibility-and-localization/internationalization