madteacher

flutter-internationalization

15
4
# Install this skill:
npx skills add MADTeacher/mad-agents-skills --skill "flutter-internationalization"

Install specific skill from multi-skill repository

# Description

Complete guide for internationalizing Flutter apps using gen-l10n and intl packages. Use when Claude needs to add localization support to Flutter applications, translate UI text, format numbers/dates for different locales, or configure multi-language support for Material/Cupertino apps.

# SKILL.md


name: flutter-internationalization
description: Complete guide for internationalizing Flutter apps using gen-l10n and intl packages. Use when Claude needs to add localization support to Flutter applications, translate UI text, format numbers/dates for different locales, or configure multi-language support for Material/Cupertino apps.


Flutter Internationalization

Overview

Comprehensive guide for adding internationalization (i18n) to Flutter applications. Covers setup, configuration, message management, number/date formatting, and advanced topics like locale override and custom language support.

Quick Start

Choose approach based on app needs:

gen-l10n (Recommended) - Modern, automated, code generation
- Best for: Most new projects, teams, complex apps
- Uses: ARB files, automated code generation
- See: Setup gen-l10n

intl package - Manual control, code-based
- Best for: Simple apps, legacy projects, full control
- Uses: Intl.message() code, manual translation files
- See: Setup intl package

Manual/Custom - Maximum flexibility
- Best for: Very simple apps, custom workflows
- Uses: Direct Map-based lookups
- See: Custom localizations

Setup gen-l10n

1. Add Dependencies

Update pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

Run:

flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any

2. Enable Code Generation

Add to pubspec.yaml:

flutter:
  generate: true

3. Configure l10n.yaml

Create l10n.yaml in project root:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

For advanced options, see l10n-config.md.

4. Create ARB Files

Create directory lib/l10n/.

Template file lib/l10n/app_en.arb:

{
  "helloWorld": "Hello World!",
  "@helloWorld": {
    "description": "Greeting message"
  }
}

Translation file lib/l10n/app_es.arb:

{
  "helloWorld": "Β‘Hola Mundo!"
}

For complete ARB format, see arb-format.md.

5. Generate Code

Run:

flutter gen-l10n

Or run app to trigger auto-generation:

flutter run

6. Configure MaterialApp

Import and setup:

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

MaterialApp(
  localizationsDelegates: [
    AppLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: [
    Locale('en'),
    Locale('es'),
  ],
  home: MyHomePage(),
)

7. Use Localizations

Access in widgets:

Text(AppLocalizations.of(context)!.helloWorld)

Message Types

Simple Messages

No parameters:

{
  "welcome": "Welcome to our app",
  "@welcome": {
    "description": "Welcome message"
  }
}

Placeholder Messages

With parameters:

{
  "greeting": "Hello {userName}!",
  "@greeting": {
    "description": "Personalized greeting",
    "placeholders": {
      "userName": {
        "type": "String",
        "example": "Alice"
      }
    }
  }
}

Use in code:

Text(AppLocalizations.of(context)!.greeting('Alice'))

Plural Messages

Based on count:

{
  "itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
  "@itemCount": {
    "placeholders": {
      "count": {
        "type": "int"
      }
    }
  }
}

Use in code:

Text(AppLocalizations.of(context)!.itemCount(5))

Select Messages

Based on string value:

{
  "pronoun": "{gender, select, male{he} female{she} other{they}}",
  "@pronoun": {
    "placeholders": {
      "gender": {
        "type": "String"
      }
    }
  }
}

Use in code:

Text(AppLocalizations.of(context)!.pronoun('male'))

Number and Date Formatting

Numbers

Format numbers automatically:

{
  "price": "Price: {value}",
  "@price": {
    "placeholders": {
      "value": {
        "type": "int",
        "format": "simpleCurrency"
      }
    }
  }
}

Format options: compact, currency, simpleCurrency, decimalPattern, etc.

Dates

Format dates automatically:

{
  "eventDate": "Event on {date}",
  "@eventDate": {
    "placeholders": {
      "date": {
        "type": "DateTime",
        "format": "yMMMd"
      }
    }
  }
}

Format options: yMd, yMMMd, yMMMMd, Hm, etc.

For complete formatting options, see number-date-formats.md.

Advanced Topics

Locale Override

Override locale for specific widgets:

Localizations.override(
  context: context,
  locale: const Locale('es'),
  child: CalendarDatePicker(...),
)

Custom Locale Definitions

For complex locales (Chinese, French regions):

supportedLocales: [
  Locale.fromSubtags(languageCode: 'zh'),
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hans'),
  Locale.fromSubtags(languageCode: 'zh', scriptCode: 'Hant', countryCode: 'TW'),
]

Locale Resolution Callback

Control locale fallback:

MaterialApp(
  localeResolutionCallback: (locale, supportedLocales) {
    // Always accept user's locale
    return locale;
  },
)

Access Current Locale

Get current app locale:

Locale myLocale = Localizations.localeOf(context);

Setup intl Package

Manual Setup

  1. Add dependencies (same as gen-l10n)
  2. Create localization class:
class DemoLocalizations {
  DemoLocalizations(this.localeName);

  static Future<DemoLocalizations> load(Locale locale) {
    final String name = Intl.canonicalizedLocale(locale.toString());
    return initializeMessages(name).then((_) => DemoLocalizations(name));
  }

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

  String get title {
    return Intl.message(
      'Hello World',
      name: 'title',
      desc: 'Title',
      locale: localeName,
    );
  }
}
  1. Create delegate:
class DemoLocalizationsDelegate extends LocalizationsDelegate<DemoLocalizations> {
  const DemoLocalizationsDelegate();

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

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

  @override
  bool shouldReload(DemoLocalizationsDelegate old) => false;
}
  1. Generate ARB files:
dart run intl_translation:extract_to_arb --output-dir=lib/l10n lib/main.dart
dart run intl_translation:generate_from_arb --output-dir=lib/l10n lib/main.dart lib/l10n/intl_*.arb

Custom Localizations

For maximum simplicity:

class DemoLocalizations {
  DemoLocalizations(this.locale);

  final Locale locale;

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

  static const _localizedValues = <String, Map<String, String>>{
    'en': {'title': 'Hello World'},
    'es': {'title': 'Hola Mundo'},
  };

  String get title {
    return _localizedValues[locale.languageCode]!['title']!;
  }
}

Best Practices

  1. Use gen-l10n for new projects - simpler, safer, better tooling
  2. Add descriptions to ARB entries - provides context for translators
  3. Format numbers/dates with format types - automatic locale handling
  4. Test all locales - verify formatting, RTL, and translations
  5. Use pluralization - handle count variations correctly
  6. Keep messages short - easier to translate, more consistent
  7. Don't concatenate strings - use placeholders instead
  8. Enable nullable-getter to reduce null checks in user code

Resources

references/

l10n-config.md - Complete reference for l10n.yaml configuration options, including output directories, code generation settings, and locale handling.

arb-format.md - Comprehensive guide to ARB file format, covering simple messages, placeholders, plurals, selects, and metadata.

number-date-formats.md - Number and date formatting reference with format types, patterns, and locale-specific examples.

assets/

Example templates and boilerplate code can be added here for common internationalization patterns.

When to Use This Skill

Use this skill when:
- Adding localization support to a new Flutter app
- Translating existing Flutter app to multiple languages
- Configuring number/date formatting for different locales
- Setting up RTL (right-to-left) language support
- Implementing locale-specific layouts or widgets
- Managing ARB files and translations
- Troubleshooting localization issues
- Adding custom language support beyond built-in locales
- Optimizing app bundle size with deferred loading

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.