modular_l10n

Pub Version Pub Points Popularity License

Optional runtime utilities for modular Flutter localization with full RTL support.


This package is optional. The Modular Flutter Localization VS Code extension works standalone with just intl as a dependency. Install this package only if you need LocaleProvider, context.setLocale(), or RTL utilities.

Features

Feature Description
RTL Support Built-in detection for Arabic, Hebrew, Urdu, and other RTL languages
LocaleProvider Easy runtime locale switching with InheritedWidget
Locale Utilities Parse, match, and get display names for locales
Cross-Platform Works on Android, iOS, Web, macOS, Windows, and Linux

Installation

Add to your pubspec.yaml:

dependencies:
  modular_l10n: ^1.0.0

Then run:

flutter pub get

Quick Start

Using LocaleProvider

Wrap your MaterialApp with LocaleProvider to enable context.setLocale() from anywhere:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:modular_l10n/modular_l10n.dart';
import 'generated/l10n/l10n.dart';

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Locale _locale = const Locale('en');

  @override
  Widget build(BuildContext context) {
    return LocaleProvider(
      initialLocale: _locale,
      onBeforeLocaleChanged: (locale) => S.load(locale),
      onLocaleChanged: (locale) {
        setState(() => _locale = locale);
      },
      child: MaterialApp(
        locale: _locale,
        supportedLocales: S.supportedLocales,
        localizationsDelegates: const [
          S.delegate,
          GlobalMaterialLocalizations.delegate,
          GlobalWidgetsLocalizations.delegate,
          GlobalCupertinoLocalizations.delegate,
        ],
        home: const HomePage(),
      ),
    );
  }
}

Then change locale from anywhere:

// In a button callback
context.setLocale(const Locale('ar'));

And access translations in widgets with S.of(context):

Text(S.of(context).auth.email)

Without this package (Cubit example)

You don't need this package to use the extension. Here's an example using a Cubit:

// locale_cubit.dart
class LocaleCubit extends Cubit<Locale> {
  LocaleCubit() : super(const Locale('en'));
  void setLocale(Locale locale) => emit(locale);
}

// main.dart
class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocProvider(
      create: (_) => LocaleCubit(),
      child: BlocBuilder<LocaleCubit, Locale>(
        builder: (context, locale) {
          return MaterialApp(
            locale: locale,
            supportedLocales: S.supportedLocales,
            localizationsDelegates: const [
              S.delegate,
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              GlobalCupertinoLocalizations.delegate,
            ],
            home: const HomePage(),
          );
        },
      ),
    );
  }
}

// Change locale from anywhere
context.read<LocaleCubit>().setLocale(const Locale('ar'));

// Access translations
Text(S.of(context).auth.email)

RTL Support

Check if Locale is RTL

import 'package:modular_l10n/modular_l10n.dart';

// Using static method
if (LocaleUtils.isRtl(locale)) {
  // Handle RTL layout
}

// Using extension
if (locale.isRtl) {
  // Handle RTL layout
}

Get Text Direction

// Using static method
TextDirection direction = LocaleUtils.getTextDirection(locale);

// Using extension
TextDirection direction = locale.textDirection;

Supported RTL Languages

Code Language
ar Arabic
fa Persian/Farsi
he Hebrew
ur Urdu
ps Pashto
sd Sindhi
yi Yiddish
ku Kurdish (Sorani)
ug Uyghur
dv Divehi

Locale Utilities

Parse Locale String

Locale locale1 = LocaleUtils.parseLocale('en');      // Locale('en')
Locale locale2 = LocaleUtils.parseLocale('en_US');   // Locale('en', 'US')
Locale locale3 = LocaleUtils.parseLocale('en-US');   // Locale('en', 'US')

Find Best Matching Locale

final supportedLocales = [Locale('en'), Locale('ar'), Locale('de')];
final deviceLocale = Locale('ar', 'EG');

Locale? match = LocaleUtils.findBestMatch(deviceLocale, supportedLocales);
// Returns Locale('ar')

Get Locale Display Names

Locale locale = Locale('ar');

// English name
String displayName = locale.displayName;     // "Arabic"

// Native name
String nativeName = locale.nativeName;       // "العربية"

API Reference

LocaleProvider

A widget that provides locale state to the widget tree.

LocaleProvider({
  required Locale initialLocale,
  required Widget child,
  ValueChanged<Locale>? onLocaleChanged,
  Future<void> Function(Locale)? onBeforeLocaleChanged,
})
Parameter Description
initialLocale The initial locale to use
child The child widget (usually MaterialApp)
onLocaleChanged Called after the locale state is updated (use for persistence)
onBeforeLocaleChanged Async callback awaited before state update (use to pre-load translations via S.load)

LocaleProviderState

Method Description
currentLocale Get the current locale
setLocale(Locale) Change the current locale (returns Future<void>)
isLocale(String) Check if current locale matches a language code

BuildContext Extensions

Extension Description
context.currentLocale Get current locale from LocaleProvider
context.setLocale(Locale) Set locale via LocaleProvider
context.isLocale(String) Check if current locale matches

LocaleUtils

Method Description
isRtl(Locale) Check if locale is RTL
getTextDirection(Locale) Get TextDirection for locale
parseLocale(String) Parse locale string to Locale
findBestMatch(Locale, List<Locale>) Find best matching locale
getDisplayName(Locale) Get English display name
getNativeName(Locale) Get native display name

Locale Extensions

Extension Description
locale.isRtl Check if locale is RTL
locale.textDirection Get TextDirection
locale.displayName Get English display name
locale.nativeName Get native display name

VS Code Extension

This package is designed to work with the Modular Flutter Localization VS Code extension.

The extension provides:

  • Automatic code generation from ARB files
  • Watch mode for instant regeneration
  • Commands to add keys and create modules
  • Modular organization by feature

Issues & Contributions

Found a bug or have a feature request?

License

This project is licensed under the MIT License - see the LICENSE file for details.


Made with care by Utanium

Libraries

modular_l10n
A modular approach to Flutter localization.