l10n_gen

Generates Dart localization files from JSON, making them easier to work with leveraging Dart's type system.

Features

  1. Catch missing translations at compile time
  2. Split translations into groups to keep them organized
  3. Format strings with variables (e.g., "Hello {name}")
  4. Generate documentation from translation comments
  5. Keep all your locales in simple JSON files

Installation

Add l10n_gen as a dev dependency and intl and flutter_localizations as dependencies in your pubspec.yaml:

dependencies:
  intl: ^0.18.0
  flutter_localizations:
    sdk: flutter

dev_dependencies:
  l10n_gen: ^1.0.0

Project Setup

  1. Create an l10n directory in your project root
  2. Create a config.json file in the l10n directory
  3. Create subdirectories for your translation groups
  4. Add JSON translation files for each supported locale

Example project structure:

your_project/
├── l10n/
│   ├── config.json
│   ├── home/
│   │   ├── en.json
│   │   └── sw.json
│   └── settings/
│       ├── en.json
│       └── sw.json
└── pubspec.yaml

Configuration

Create l10n/config.json to customize the generator:

{
    "to": "lib/localizations",         // Output directory for generated files
    "main_locale": "en",              // Main locale for documentation
    "supported_locales": ["en", "sw"]  // List of supported locales
}

All fields are required.

Writing Translations

Simple Translations

For simple translations, create JSON files with key-value pairs:

l10n/settings/en.json:

{
    "settings": "Settings",
    "darkMode": "Dark Mode",
    "language": "Language"
}

l10n/settings/sw.json:

{
    "settings": "Mipangilio",
    "darkMode": "Hali ya Giza",
    "language": "Lugha"
}

Grouped Translations

For grouped translations, use arrays with _id to create separate classes:

l10n/home/en.json:

[
    {
        "_id": "home",
        "title": "Home",
        "welcome": "Welcome back",
        "notifications": "You have {count} notifications"
    }
]

l10n/home/sw.json:

[
    {
        "_id": "home",
        "title": "Nyumbani",
        "welcome": "Karibu tena",
        "notifications": "Una arifa {count}"
    }
]

Using Placeholders

You can add metadata for placeholders in the main locale file:

l10n/forms/en.json:

{
    "isRequired": "{field} is required",
    "@isRequired": {
        "description": "Used in forms when a required field is empty",
        "placeholders": {
            "field": {
                "type": "String"
            }
        }
    }
}

Running the Generator

Run the generator using:

l10n_gen

This will:

  1. Read all translation files
  2. Generate type-safe Dart classes
  3. Create the base localization class
  4. Create locale-specific implementation classes

Using Generated Code

The generator creates several files:

lib/localizations/
├── app_localizations.dart      // Base abstract class
├── app_localizations_en.dart   // English implementations
└── app_localizations_sw.dart   // Swahili implementations

Setup in Flutter

Add the following to your MaterialApp:

import 'package:your_app/localizations/app_localizations.dart';

MaterialApp(
  // ... other properties ...
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
);

Using Translations

Access translations using the generated methods:

// Simple translations
final settings = AppLocalizations.of(context)!.settings;

// Group translations
final homeTitle = AppLocalizations.of(context)!.home.title;

// Translations with placeholders
final error = AppLocalizations.of(context)!.isRequired('Email');

Type Safety

The generator creates strongly-typed classes, ensuring:

  • All translations are present in all locale files
  • Placeholder types are correctly enforced
  • Missing translations are caught at compile time

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.