DEV3 Technologies home

RTL and localization setup

Locale-aware MaterialApp with a hand-written localisation delegate, switchable language and direction-safe layout helpers.

FlutterInternationalisationflutterl10nrtllocale

Code

import 'package:flutter/widgets.dart';

class AppStrings {
  AppStrings(this.locale);
  final Locale locale;

  static const supported = [Locale('en'), Locale('ar')];
  static const _table = <String, Map<String, String>>{
    'en': {'book': 'Book now', 'greeting': 'Hello, {name}'},
    'ar': {'book': 'احجز الآن', 'greeting': 'مرحبا، {name}'},
  };

  static AppStrings of(BuildContext c) => Localizations.of<AppStrings>(c, AppStrings)!;

  String _t(String k) => _table[locale.languageCode]?[k] ?? _table['en']![k]!;
  String get book => _t('book');
  String greeting(String name) => _t('greeting').replaceAll('{name}', name);

  static const delegate = _Delegate();
}

class _Delegate extends LocalizationsDelegate<AppStrings> {
  const _Delegate();
  @override
  bool isSupported(Locale l) => AppStrings.supported.any((s) => s.languageCode == l.languageCode);
  @override
  Future<AppStrings> load(Locale l) async => AppStrings(l); // synchronous table
  @override
  bool shouldReload(_Delegate old) => false;
}

How it works

What it solves

Apps for salons and similar local services are often used in Arabic or Hebrew as well as English. Supporting that is not just translating text: the whole layout must mirror and strings must be reachable from any widget.

How it works

AppStrings is a minimal localisation class: a map per language, a fallback to English, and a placeholder replacement for names. Its LocalizationsDelegate tells Flutter which languages are supported and loads the strings.

LanguageApp registers that delegate next to the framework delegates. GlobalWidgetsLocalizations is the one that supplies the text direction, so Arabic automatically flips the app bar, drawers and back arrows. A nullable locale follows the device until the user picks a language from the buttons.

Adapting it

For many strings or plural rules, move to Flutter's gen_l10n with ARB files; the usage pattern (context.l10n.book) stays the same. Replace the state lookup with a provider or a controller if you persist the choice. Always write padding and alignment with their Directional versions.

Pitfalls

  • Add the flutter_localizations SDK dependency and intl, otherwise the framework delegates do not compile.
  • Numbers and dates are formatted by intl per locale; do not build them by string concatenation.
  • Icons with direction, such as arrows, need matchTextDirection or the Directionality check.

How to use it

Add to pubspec.yaml: flutter_localizations with sdk: flutter, plus intl. Copy both files into lib/l10n/.

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

Read text with AppStrings.of(context).book from any widget.

Licence: DEV3 Snippet Licence. Free to use, change and ship in personal and commercial projects. Attribution is appreciated, not required. Please do not redistribute snippets as a collection.

Related snippets