Jaspr Localizations

** Made by 🦏 zoocityboy with ❤️ for the Jaspr community **

Pub Version License Dart Jaspr

Jaspr Localizations

Internationalization and localization support for Jaspr applications with ARB file generation and Flutter-like APIs.

Features

  • 🔒 Type-Safe Localization - Compile-time safety with generated Dart classes
  • 📦 ARB File Support - Industry-standard format compatible with Flutter
  • 🌐 Platform-Aware Detection - Automatic language detection from browser/system
  • 🔄 Dynamic Locale Switching - Runtime locale changes with automatic UI rebuilding
  • 📝 ICU MessageFormat - Support for plurals, selects, and complex formatting
  • Performance Optimized - Minimal runtime overhead using InheritedComponent

Installation

Add to your pubspec.yaml:

dependencies:
  jaspr_localizations: ^1.0.0

dev_dependencies:
  build_runner: ^2.4.0

Install dependencies:

dart pub get

Quick Start

1. Configure Localization

Create l10n.yaml in your project root:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: generated/l10n.dart
output-class: AppLocalizations

2. Create ARB Files

Create translation files in lib/l10n/:

lib/l10n/app_en.arb:

{
  "@@locale": "en",
  "appTitle": "My Application",
  "welcomeMessage": "Welcome, {name}!",
  "@welcomeMessage": {
    "placeholders": {
      "name": {"type": "String"}
    }
  }
}

lib/l10n/app_es.arb:

{
  "@@locale": "es",
  "appTitle": "Mi Aplicación",
  "welcomeMessage": "¡Bienvenido, {name}!"
}

3. Generate Code

dart run build_runner build

Usage

Basic Setup

Wrap your app with JasprLocalizations:

import 'package:jaspr/jaspr.dart';
import 'package:jaspr_localizations/jaspr_localizations.dart';
import 'generated/l10n.dart';

@client
class App extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return JasprLocalizations(
      supportedLocales: [
        Locale('en', 'US'),
        Locale('es', 'ES'),
        Locale('fr', 'FR'),
      ],
      initialLocale: getCurrentLocale(), // Auto-detect user's language
      delegates: [AppLocalizations.delegate],
      builder: (context, locale) => HomePage(),
    );
  }
}

Accessing Translations

Use the generated localization class:

class HomePage extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    
    return div([
      h1([text(l10n.appTitle)]),
      p([text(l10n.welcomeMessage('Jaspr'))]),
    ]);
  }
}

Changing Locale

Create a language switcher:

class LanguageSwitcher extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    final provider = JasprLocalizationProvider.of(context);
    final currentLocale = provider.currentLocale;
    
    return div([
      for (final locale in provider.supportedLocales)
        button(
          classes: currentLocale == locale ? 'active' : '',
          onClick: () => JasprLocalizationProvider.setLocale(context, locale),
          [text(locale.languageCode.toUpperCase())],
        ),
    ]);
  }
}

Locale Override with withLocale

The JasprLocalizations.withLocale method allows you to display specific content in a different locale without changing the app's global locale.

Use Cases

  • Previews - Show content in multiple languages simultaneously
  • Side-by-side translations - Compare translations
  • Testing - Verify translations without app-wide changes

Example: Multi-Language Preview

class LanguagePreview extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return div([
      h2([text('Preview in Multiple Languages')]),
      
      // English
      div([
        h3([text('English')]),
        JasprLocalizations.withLocale(
          locale: Locale('en', 'US'),
          child: WelcomeMessage(),
        ),
      ]),
      
      // Spanish
      div([
        h3([text('Spanish')]),
        JasprLocalizations.withLocale(
          locale: Locale('es', 'ES'),
          child: WelcomeMessage(),
        ),
      ]),
      
      // French
      div([
        h3([text('French')]),
        JasprLocalizations.withLocale(
          locale: Locale('fr', 'FR'),
          child: WelcomeMessage(),
        ),
      ]),
    ]);
  }
}

class WelcomeMessage extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    final l10n = AppLocalizations.of(context);
    return p([text(l10n.welcomeMessage('User'))]);
  }
}

Example: Side-by-Side Translation

class TranslationComparison extends StatelessComponent {
  @override
  Component build(BuildContext context) {
    return div([
      // Current language
      div([
        h4([text('Current')]),
        ProductDescription(),
      ]),
      
      // Preview in another language
      div([
        h4([text('Translation')]),
        JasprLocalizations.withLocale(
          locale: Locale('es', 'ES'),
          child: ProductDescription(),
        ),
      ]),
    ]);
  }
}

Important: The overridden locale must be in the supportedLocales list.

Platform-Aware Detection

Automatically detect user's language:

// Get current locale
final locale = getCurrentLocale();

// Use in app
JasprLocalizations(
  initialLocale: getCurrentLocale(),
  ...
)

Detection sources:

  • Browser: navigator.language
  • Server: Intl.getCurrentLocale()
  • Fallback: 'en'

ICU MessageFormat

Pluralization

{
  "itemCount": "{count, plural, =0{No items} =1{One item} other{{count} items}}"
}
l10n.itemCount(0);  // "No items"
l10n.itemCount(1);  // "One item"
l10n.itemCount(5);  // "5 items"

Select Messages

{
  "greeting": "{gender, select, male{Mr.} female{Ms.} other{}} Hello"
}
l10n.greeting('male');    // "Mr. Hello"
l10n.greeting('female');  // "Ms. Hello"

Troubleshooting

Build fails:

dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs

Translations missing:

  • All ARB files must have the same keys
  • Run build_runner after changes

Locale not changing:

  • Use JasprLocalizations, not just JasprLocalizationProvider
  • Verify locale is in supportedLocales

Resources

License

MIT License - see LICENSE

Libraries

builder
jaspr_localizations
Jaspr Localizations - Internationalization and localization for Jaspr applications.