Skip to content
Blog

Flutter Localization Delegates: The Complete Configuration Guide

Master Flutter localization delegates including AppLocalizations, GlobalMaterialLocalizations, and GlobalCupertinoLocalizations for proper locale support.

Published on September 19, 2026

AI Assistant

Flutter Localization Delegates: The Complete Configuration Guide

Localization delegates are the glue that connects Flutter’s localization system to your app. They tell Flutter how to load localized data, format dates and numbers, and provide locale-specific widget behavior. Understanding delegates is essential for proper multi-language support.

What Are Localization Delegates?

A localization delegate is a class that provides localized values for a specific aspect of your app. Flutter uses them to:

  1. Load translation data — your ARB file content
  2. Format locale-specific data — dates, numbers, currencies
  3. Provide widget localization — Material and Cupertino widgets

The Four Essential Delegates

1. AppLocalizations.delegate (Your Translations)

This delegate is generated from your ARB files and provides access to all your translated strings:

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate, // Your translations
        // ...
      ],
    );
  }
}

2. GlobalMaterialLocalizations (Material Widgets)

Provides localized names for Material Design widgets (OK, Cancel, January, etc.):

import 'package:flutter_localizations/flutter_localizations.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate, // Material widget names
        // ...
      ],
    );
  }
}

3. GlobalWidgetsLocalizations (Text Direction)

Handles text direction and text rendering:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate, // Text direction
        // ...
      ],
    );
  }
}

4. GlobalCupertinoLocalizations (Cupertino Widgets)

Provides localized names for iOS-style widgets:

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate, // iOS widget names
      ],
    );
  }
}

Complete Configuration

Minimal Setup

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
      home: const HomeScreen(),
    );
  }
}

With Custom Locale Resolution

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
      localeResolutionCallback: (locale, supportedLocales) {
        // Custom resolution logic
        for (final supportedLocale in supportedLocales) {
          if (supportedLocale.languageCode == locale?.languageCode) {
            return supportedLocale;
          }
        }
        return supportedLocales.first; // Default to English
      },
      home: const HomeScreen(),
    );
  }
}

Using Delegates in Widgets

Accessing Translations

class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context) {
    // Access your translations
    final l10n = AppLocalizations.of(context)!;

    return Column(
      children: [
        Text(l10n.appTitle),
        Text(l10n.welcomeMessage),
        ElevatedButton(
          onPressed: () {},
          child: Text(l10n.loginButton),
        ),
      ],
    );
  }
}

Accessing Material Localizations

class DatePickerWidget extends StatelessWidget {
  const DatePickerWidget({super.key});

  @override
  Widget build(BuildContext context) {
    // Access Material localizations
    final materialLocalizations = MaterialLocalizations.of(context);

    return TextButton(
      onPressed: () {
        showDatePicker(
          context: context,
          initialDate: DateTime.now(),
          firstDate: DateTime(2020),
          lastDate: DateTime(2030),
        );
      },
      child: const Text('Select Date'),
    );
  }
}

Advanced: Custom Localization Delegates

Creating a Custom Delegate

class CustomLocalizations {
  final Locale locale;

  CustomLocalizations(this.locale);

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

  static const LocalizationsDelegate<CustomLocalizations> delegate =
      _CustomLocalizationsDelegate();

  // Custom localized data
  String get appName => locale.languageCode == 'es' ? 'Mi App' : 'My App';
}

class _CustomLocalizationsDelegate
    extends LocalizationsDelegate<CustomLocalizations> {
  const _CustomLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) {
    return ['en', 'es'].contains(locale.languageCode);
  }

  @override
  Future<CustomLocalizations> load(Locale locale) async {
    return CustomLocalizations(locale);
  }

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

Using Custom Delegates

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: const [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
        CustomLocalizations.delegate, // Your custom delegate
      ],
      supportedLocales: const [
        Locale('en', ''),
        Locale('es', ''),
      ],
    );
  }
}

Debugging Delegates

Checking Loaded Locales

class DebugLocaleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final locale = Localizations.localeOf(context);
    final l10n = AppLocalizations.of(context);

    return Text(
      'Current locale: ${locale.languageCode}\n'
      'Translations loaded: ${l10n != null}',
    );
  }
}

Handling Missing Translations

// In l10n.yaml, set:
nullable-localization: false

// Then use:
final l10n = AppLocalizations.of(context)!; // Throws if null

// Or provide fallback:
final l10n = AppLocalizations.of(context) ?? AppLocalizations.defaultLocalization;

Common Pitfalls

Missing Delegates

// Bad: Missing GlobalWidgetsLocalizations breaks RTL support
localizationsDelegates: const [
  AppLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
]

// Good: Include all four delegates
localizationsDelegates: const [
  AppLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
  GlobalCupertinoLocalizations.delegate,
]

Wrong Order

// Bad: AppLocalizations.delegate should come first
localizationsDelegates: const [
  GlobalMaterialLocalizations.delegate,
  AppLocalizations.delegate,
]

// Good: AppLocalizations.delegate first
localizationsDelegates: const [
  AppLocalizations.delegate,
  GlobalMaterialLocalizations.delegate,
  GlobalWidgetsLocalizations.delegate,
  GlobalCupertinoLocalizations.delegate,
]

Resources

Localization delegates are the foundation of Flutter’s multi-language support. By properly configuring them, you ensure your app works correctly across all supported locales.