localization_gen 2.3.1 copy "localization_gen: ^2.3.1" to clipboard
localization_gen: ^2.3.1 copied to clipboard

Type-safe Flutter localization generator from JSON/JSONC, with nested keys, placeholders, and plural/gender/context variants.

Localization Generator #

Type-safe localization code generator for Flutter applications using nested JSON files.

Pub Version License

Overview #

Generate type-safe, nested localization code from JSON files with compile-time checking, parameter interpolation, and strict validation support.

Repository: https://github.com/alpinnz/localization_gen

Features #

  • Type-Safe: Compile-time checking of translation keys
  • Nested Structure: Organize translations hierarchically (up to 10 levels)
  • Watch Mode: Auto-regenerate on file changes
  • Parameter Support: Named parameters with type checking
  • Strict Validation: Ensure consistency across all locales
  • Field Rename: Support multiple naming conventions (snake_case, kebab-case, etc.)
  • Modular Organization: Feature-based file structure
  • Monorepo Support: Multiple packages with independent localization

Installation #

Add to your pubspec.yaml:

dev_dependencies:
  localization_gen: ^2.1.0

dependencies:
  flutter_localizations:
    sdk: flutter

Install dependencies:

dart pub get

Quick Start #

1. Configuration #

Add configuration to pubspec.yaml:

localization_gen:
  input_dir: assets/localizations
  output_dir: lib/assets
  class_name: AppLocalizations

  # Optional (defaults shown)
  file_pattern: app_{module}_{locale}.json
  file_prefix: app

  # Optional (default: camel)
  # JSON keys are recommended to be snake_case (e.g. welcome_user)
  # Generated Dart API becomes camelCase (e.g. welcomeUser)
  field_rename: camel  # none, kebab, snake, pascal, camel, screamingSnake

2. Create JSON Files (modular-only) #

This package is modular-only. Every file MUST include:

  • @@locale
  • @@module

Canonical spec: .jsonc (commented, developer-readable). Generator input: .json (strict JSON).

Create assets/localizations/app_common_en.json:

{
  "@@locale": "en",
  "@@module": "common",
  "strings": { "app_title": "Demo App" },
  "simple": { "hello": "Hello" },
  "placeholders": { "welcome_user": "Welcome, {name}." }
}

Create assets/localizations/app_common_id.json:

{
  "@@locale": "id",
  "@@module": "common",
  "strings": { "app_title": "Aplikasi Demo" },
  "simple": { "hello": "Halo" },
  "placeholders": { "welcome_user": "Selamat datang, {name}." }
}

Supported Cases (CASE 1–15) #

The canonical dataset lives in this repository under:

  • assets/localizations/app_common_en.jsonc
  • assets/localizations/app_common_id.jsonc

The dataset is designed to cover the most common localization cases, each appearing once:

  1. @@locale metadata
  2. @@module metadata
  3. Basic strings (namespace: strings.*)
  4. Nested keys (flattened dot-keys; recommended max depth 6)
  5. Placeholders {name} (named parameters)
  6. Multiple placeholders in one message
  7. Placeholder reordering across locales
  8. Per-key metadata (inline-only)
    • Inline: @description, @example, @placeholders, plus custom @<name>
    • For string keys with metadata: wrap using @value
  9. Newline escaping (\n)
  10. Quote escaping (\")
  11. Unicode punctuation
  12. Symbols inside strings (URLs/email/bullets/legal marks)
  13. Literal tokens that are not placeholders (e.g. {{...}}, [x])
  14. Literal braces { and }
  15. Structured forms: @plural, @gender, @context

If you need a working .json dataset for generation, mirror the JSONC structure into .json files (remove comments).

Development Commands #

Use full commands (cross-platform):

# Install

dart pub get

# Quality

dart format .
dart analyze
dart test

# Flutter (if you want to run the example app tests)

flutter test

# Generate once

dart run localization_gen generate

# Generate (watch mode)

dart run localization_gen generate --watch

# Validate

dart run localization_gen validate

# Clean generated output

dart run localization_gen clean

# Coverage

dart run localization_gen coverage

4. Setup Flutter App #

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        AppLocalizationsExtension.delegate,
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: AppLocalizations.supportedLocales,
      home: HomePage(),
    );
  }
}

5. Use Translations #

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        // JSON: strings.app_title
        // Dart: strings.appTitle
        title: Text(AppLocalizations.of(context).strings.appTitle),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          // JSON: simple.hello
          Text(AppLocalizations.of(context).simple.hello),

          // JSON: placeholders.welcome_user
          Text(AppLocalizations.of(context).placeholders.welcomeUser(name: 'John')),

          // Runtime lookup (no placeholder interpolation; use typed API for placeholders)
          Text(AppLocalizations.of(context).resolveByKey('strings.app_title', fallback: '<missing>') ?? '<missing>'),
          Text(AppLocalizations.of(context).resolveByKey('app_title', namespace: 'strings', fallback: '<missing>') ?? '<missing>'),
        ],
      ),
    );
  }
}

Commands #

Generate #

# Generate once

dart run localization_gen generate

# Watch mode (auto-regenerate on changes)

dart run localization_gen generate --watch

Initialize #

# Create directory structure and sample files

dart run localization_gen init

Validate #

# Validate JSON files

dart run localization_gen validate

Clean #

# Remove generated files

dart run localization_gen clean

Coverage #

# Generate coverage report

dart run localization_gen coverage

# HTML format

dart run localization_gen coverage --format=html --output=coverage.html

Configuration Options #

localization_gen:
  # Required
  input_dir: assets/localizations

  # Optional (defaults shown)
  output_dir: lib/assets
  class_name: AppLocalizations

  # Optional: control naming of generated Dart identifiers (default: camel)
  field_rename: camel

  # Optional: modular file naming (defaults shown)
  file_pattern: app_{module}_{locale}.json
  file_prefix: app

Mandatory behavior (not configurable) #

This package always enforces the following:

  • BuildContext access is always available: AppLocalizations.of(context) is generated.
  • Non-nullable access: of(context) returns a non-null instance.
  • Modular-only input: every file must include @@locale and @@module.
  • Strict validation is always enabled: keys and placeholders must match across locales.

Field Rename Options #

Control how JSON keys are converted to Dart identifiers:

  • none: Keep original naming
  • kebab: user-name
  • snake: user_name
  • pascal: UserName
  • camel: userName (default)
  • screamingSnake: USER_NAME

Example:

localization_gen:
  field_rename: camel

JSON:

{
  "userProfile": {
    "firstName": "First Name"
  }
}

Generated (with camelCase):

AppLocalizations.of(context).userProfile.firstName;

Advanced Features #

Parameter Interpolation #

{
  "greeting": "Hello, {name}!",
  "items": "You have {count} items"
}
AppLocalizations.of(context).greeting(name: 'John');
AppLocalizations.of(context).items(count: '5');

Pluralization #

{
  "items": {
    "@plural": {
      "zero": "No items",
      "one": "One item",
      "other": "{count} items"
    }
  }
}

Gender Forms #

{
  "greeting": {
    "@gender": {
      "male": "Hello Mr. {name}",
      "female": "Hello Ms. {name}",
      "other": "Hello {name}"
    }
  }
}

Context Forms #

{
  "invitation": {
    "@context": {
      "formal": "We cordially invite you",
      "informal": "Come join us"
    }
  }
}

Nested Structure (10 Levels) #

{
  "level1": {
    "level2": {
      "level3": {
        "message": "Deeply nested translation"
      }
    }
  }
}
AppLocalizations.of(context).level1.level2.level3.message;

Watch Mode #

dart run localization_gen generate --watch

Automatically regenerates code when JSON files change.

Strict Validation #

Strict validation is always enabled (no configuration needed).

Modular Organization #

This package is modular-only. File naming follows:

  • app_{module}_{locale}.json

Recommended file structure:

assets/localizations/
  app_common_en.json
  app_common_id.json

Files are merged by locale.

Examples #

See the example/ directory:

Migration Guide #

From v1.0.3 to v1.0.4+ #

Named parameters are now required:

// Before
AppLocalizations.of(context).welcome('John');

// After
AppLocalizations.of(context).welcome(name: 'John');

Troubleshooting #

Generated file not found #

By default the generator writes:

  • lib/assets/<class_name in snake_case>.gen.dart

If you override output_dir, adjust your imports accordingly.

Newline (\n) handling #

In JSON there is an important difference:

  • "Line 1\nLine 2" produces a real newline character at runtime.
  • "Line 1\\nLine 2" produces the two characters \ and n (literal backslash-n).

The generator preserves the parsed string value. If you want a real newline in the UI, store \n (single backslash) in JSON.

Best Practices #

  1. Prefer direct access: AppLocalizations.of(context).<namespace>.<key>
  2. Group related translations in nested structure
  3. Use descriptive parameter names
  4. Strict validation is always enabled
  5. Use watch mode during development
  6. Consider modular organization for large apps

Contributing #

Contributions welcome! See CONTRIBUTING.md

License #

MIT License - see LICENSE

2
likes
160
points
467
downloads

Publisher

unverified uploader

Weekly Downloads

Type-safe Flutter localization generator from JSON/JSONC, with nested keys, placeholders, and plural/gender/context variants.

Repository (GitHub)
View/report issues
Contributing

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

args, path, watcher, yaml

More

Packages that depend on localization_gen