← Back to Blog

Flutter_Localizations Package: Complete Setup Guide 2025

flutterflutter_localizationssetupl10ndelegatesofficial

Flutter_Localizations Package: Complete Setup Guide 2025

The flutter_localizations package is Flutter's official solution for internationalizing your app. It provides localized strings for Flutter widgets and integrates seamlessly with the framework's localization system.

What is flutter_localizations?

flutter_localizations is a Flutter SDK package that provides:

  • Material Design localizations - Translated strings for Material widgets
  • Cupertino localizations - Translated strings for iOS-style widgets
  • Widget localizations - Basic Flutter widget translations
  • RTL support - Right-to-left text direction for Arabic, Hebrew, etc.

Quick Start Setup

Step 1: Add Dependencies

# pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

flutter:
  generate: true

Run flutter pub get to install.

Step 2: Create l10n.yaml Configuration

Create l10n.yaml in your project root:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations
synthetic-package: true
nullable-getter: false

Step 3: Create Your First ARB File

Create the directory and template file:

mkdir -p lib/l10n

Create lib/l10n/app_en.arb:

{
  "@@locale": "en",
  "appTitle": "My Flutter App",
  "@appTitle": {
    "description": "The title of the application"
  },
  "hello": "Hello!",
  "@hello": {
    "description": "A greeting"
  },
  "welcomeUser": "Welcome, {username}!",
  "@welcomeUser": {
    "description": "Welcome message with username",
    "placeholders": {
      "username": {
        "type": "String",
        "example": "John"
      }
    }
  },
  "itemCount": "{count, plural, =0{No items} =1{One item} other{{count} items}}",
  "@itemCount": {
    "description": "Number of items",
    "placeholders": {
      "count": {
        "type": "int"
      }
    }
  }
}

Step 4: Add More Languages

Create lib/l10n/app_es.arb for Spanish:

{
  "@@locale": "es",
  "appTitle": "Mi Aplicación Flutter",
  "hello": "¡Hola!",
  "welcomeUser": "¡Bienvenido, {username}!",
  "itemCount": "{count, plural, =0{Sin elementos} =1{Un elemento} other{{count} elementos}}"
}

Create lib/l10n/app_fr.arb for French:

{
  "@@locale": "fr",
  "appTitle": "Mon Application Flutter",
  "hello": "Bonjour!",
  "welcomeUser": "Bienvenue, {username}!",
  "itemCount": "{count, plural, =0{Aucun élément} =1{Un élément} other{{count} éléments}}"
}

Step 5: Generate Localization Code

Run the generator:

flutter gen-l10n

Or simply build your app—Flutter auto-generates on build:

flutter run

Step 6: Configure MaterialApp

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Localization Demo',

      // Localization configuration
      localizationsDelegates: [
        AppLocalizations.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,

      // Optional: Set default locale
      // locale: Locale('es'),

      home: HomePage(),
    );
  }
}

Simpler syntax (using generated delegates):

MaterialApp(
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
  home: HomePage(),
)

Step 7: Use Translations in Widgets

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

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get the localization instance
    final l10n = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(
        title: Text(l10n.appTitle),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(l10n.hello),
            Text(l10n.welcomeUser('John')),
            Text(l10n.itemCount(5)),
          ],
        ),
      ),
    );
  }
}

Understanding the Delegates

GlobalMaterialLocalizations.delegate

Provides translations for Material Design widgets:

  • DatePicker (month names, weekdays)
  • TimePicker (AM/PM, hour labels)
  • Dialog buttons (OK, Cancel)
  • Form validation messages
  • Pagination controls

GlobalWidgetsLocalizations.delegate

Provides basic widget localizations:

  • Text direction (LTR/RTL)
  • Text selection controls

GlobalCupertinoLocalizations.delegate

Provides iOS-style (Cupertino) widget translations:

  • CupertinoDatePicker
  • CupertinoAlertDialog
  • CupertinoActionSheet

AppLocalizations.delegate

Your custom translations generated from ARB files.

Supported Locales

Flutter's built-in localizations support 80+ locales including:

Language Code RTL
English en No
Spanish es No
French fr No
German de No
Chinese (Simplified) zh No
Chinese (Traditional) zh_TW No
Japanese ja No
Korean ko No
Arabic ar Yes
Hebrew he Yes
Persian fa Yes
Hindi hi No
Russian ru No
Portuguese pt No

Check the full list:

import 'package:flutter_localizations/flutter_localizations.dart';

void printSupportedLocales() {
  print(GlobalMaterialLocalizations.delegate.supportedLocales);
}

Advanced Configuration

l10n.yaml Options Explained

# Required: Directory containing ARB files
arb-dir: lib/l10n

# Required: Template file (source language)
template-arb-file: app_en.arb

# Output file name
output-localization-file: app_localizations.dart

# Generated class name
output-class: AppLocalizations

# Generate as synthetic package (recommended)
synthetic-package: true

# Make getters non-nullable
nullable-getter: false

# Output directory (if not using synthetic package)
# output-dir: lib/generated

# Generate a header in output files
# header: "// Generated file - do not edit"

# Use deferred loading (for web, reduces initial bundle)
# use-deferred-loading: true

# Require descriptions for all messages
# require-description: true

# Require placeholders in messages
# require-placeholders: true

Custom Locale Resolution

MaterialApp(
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,

  // Custom resolution logic
  localeResolutionCallback: (deviceLocale, supportedLocales) {
    // Check for exact match
    for (var locale in supportedLocales) {
      if (locale.languageCode == deviceLocale?.languageCode &&
          locale.countryCode == deviceLocale?.countryCode) {
        return locale;
      }
    }

    // Check for language match
    for (var locale in supportedLocales) {
      if (locale.languageCode == deviceLocale?.languageCode) {
        return locale;
      }
    }

    // Default to first supported locale
    return supportedLocales.first;
  },
)

Dynamic Locale Switching

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

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

  void setLocale(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      locale: _locale,
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: HomePage(onLocaleChange: setLocale),
    );
  }
}

ARB File Format Deep Dive

Basic Message

{
  "greeting": "Hello",
  "@greeting": {
    "description": "A simple greeting"
  }
}

Message with Placeholder

{
  "greeting": "Hello, {name}!",
  "@greeting": {
    "description": "Greeting with name",
    "placeholders": {
      "name": {
        "type": "String",
        "example": "World"
      }
    }
  }
}

Plural Message

{
  "emails": "{count, plural, =0{No emails} =1{1 email} other{{count} emails}}",
  "@emails": {
    "description": "Email count",
    "placeholders": {
      "count": {
        "type": "int"
      }
    }
  }
}

Select Message (Gender)

{
  "userWelcome": "{gender, select, male{Welcome, Mr. {name}} female{Welcome, Ms. {name}} other{Welcome, {name}}}",
  "@userWelcome": {
    "description": "Gender-specific welcome",
    "placeholders": {
      "gender": {
        "type": "String"
      },
      "name": {
        "type": "String"
      }
    }
  }
}

Date/Time Placeholder

{
  "lastLogin": "Last login: {date}",
  "@lastLogin": {
    "description": "Shows last login date",
    "placeholders": {
      "date": {
        "type": "DateTime",
        "format": "yMMMd"
      }
    }
  }
}

Number Placeholder

{
  "price": "Price: {amount}",
  "@price": {
    "description": "Product price",
    "placeholders": {
      "amount": {
        "type": "double",
        "format": "currency",
        "optionalParameters": {
          "symbol": "$",
          "decimalDigits": 2
        }
      }
    }
  }
}

Common Issues and Solutions

"Cannot find generated localization file"

Run the generator manually:

flutter gen-l10n

Or ensure flutter: generate: true is in pubspec.yaml.

"Locale not supported"

Add the locale to your ARB files:

# Create app_de.arb for German
touch lib/l10n/app_de.arb

"Null check operator used on null value"

The locale isn't available yet. Ensure MaterialApp has the delegates:

// Wrong - accessing before localization is ready
final l10n = AppLocalizations.of(context)!; // May crash

// Right - check for null or use in widget tree
final l10n = AppLocalizations.of(context);
if (l10n != null) {
  return Text(l10n.hello);
}

RTL Not Working

Ensure you include the widgets delegate:

localizationsDelegates: [
  GlobalWidgetsLocalizations.delegate, // Required for RTL
  GlobalMaterialLocalizations.delegate,
  AppLocalizations.delegate,
],

FlutterLocalisation: Visual ARB Management

Editing ARB files manually is error-prone. FlutterLocalisation provides:

  • Visual ARB editor - No JSON syntax errors
  • Side-by-side translations - Compare all languages
  • Placeholder validation - Catch missing placeholders
  • AI translation - Instant translations for new languages
  • Export to ARB - Download ready-to-use files

Ready to streamline your Flutter localization? Try FlutterLocalisation free — the visual way to manage ARB files for flutter_localizations.