Skip to main content

Overview

Invenicum supports multiple languages out of the box with Flutter’s built-in internationalization (i18n) system. Users can switch languages on-the-fly, and all UI text adapts automatically.

Supported Languages

Invenicum currently supports 6 languages:
LanguageCodeNative Name
EnglishenEnglish
SpanishesEspañol
ItalianitItaliano
PortugueseptPortuguês
FrenchfrFrançais
GermandeDeutsch
The default language is Spanish (es), but this changes based on user preferences.

Localization Configuration

l10n.yaml

The localization setup is defined in l10n.yaml:1-11:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
untranslated-messages-file: missing_translations.txt
supported-locales:
  - en
  - es
  - it
  - pt
  - fr
  - de

pubspec.yaml

Localization dependencies are configured in pubspec.yaml:33-45:
dependencies:
  flutter_localizations:
    sdk: flutter
  intl: any

flutter:
  generate: true  # Enables automatic code generation

main.dart

Localization delegates are registered in main.dart:296-304:
MaterialApp.router(
  locale: preferencesProvider.locale,
  localizationsDelegates: const [
    AppLocalizations.delegate,
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
  ],
  supportedLocales: AppLocalizations.supportedLocales,
  // ...
)

Translation Files

Translation files are stored in ARB (Application Resource Bundle) format:
lib/l10n/
├── app_en.arb  (English - Template)
├── app_es.arb  (Spanish)
├── app_it.arb  (Italian)
├── app_pt.arb  (Portuguese)
├── app_fr.arb  (French)
└── app_de.arb  (German)

ARB File Structure

File: lib/l10n/app_en.arb:1-493 Example entries:
{
  "@@locale": "en",
  
  "appTitle": "Invenicum Inventory",
  "dashboard": "Dashboard",
  "settings": "Settings",
  "language": "Language",
  "currency": "Currency",
  
  "@fieldRequiredWithName": {
    "placeholders": {
      "field": {
        "type": "String"
      }
    }
  },
  "fieldRequiredWithName": "Field \"{field}\" is required.",
  
  "integrationGeminiDesc": "Connect Invenicum with Google's Gemini to leverage advanced AI capabilities in managing your inventory.",
  "helperGeminiKey": "Enter your Gemini API key to enable integration. Get it at https://aistudio.google.com/"
}
Entries starting with @ define metadata like placeholders. The actual translation follows with the same key minus the @.

Changing Language

User Interface

1

Open Settings

Navigate to SettingsGeneral Settings
2

Find Language Section

Locate the Language option with globe icon
3

Select Language

Click the dropdown and choose your preferred language:
  • English
  • Español (Spanish)
  • Italiano (Italian)
  • Português (Portuguese)
  • Français (French)
  • Deutsch (German)
4

Confirm Change

The app will update immediately and show:
Language changed to English!

Programmatic Usage

Preferences Provider: lib/providers/preferences_provider.dart
// Get current locale
Locale get locale => Locale(_prefs.language);

// Change language
Future<void> setLanguage(String languageCode) async {
  _prefs = _prefs.copyWith(language: languageCode);
  await _preferencesService.updateLanguage(languageCode);
  notifyListeners();
}
Preferences Service: lib/data/services/preferences_service.dart:42-48
Future<void> updateLanguage(String languageCode) async {
  await _dio.put('/preferences/language', 
    data: {'language': languageCode}
  );
}
API Endpoint: PUT /api/v1/preferences/language
{
  "language": "en"
}

Using Translations in Code

Access Localizations

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

class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // Get localizations instance
    final l10n = AppLocalizations.of(context)!;
    
    return Text(l10n.dashboard);  // "Dashboard" in selected language
  }
}

Simple Strings

Text(AppLocalizations.of(context)!.settings)
Text(AppLocalizations.of(context)!.language)
Text(AppLocalizations.of(context)!.currency)

Strings with Placeholders

// ARB definition
{
  "fieldRequiredWithName": "Field \"{field}\" is required."
}

// Usage
AppLocalizations.of(context)!.fieldRequiredWithName("Email")
// Output: "Field \"Email\" is required."

AppLocalizations.of(context)!.veniChatProcessing("inventory status")
// Output: "I'm processing your query about \"inventory status\"..."

Integration-Specific Translations

final l10n = AppLocalizations.of(context)!;

IntegrationConfig(
  id: 'gemini',
  name: 'Google Gemini AI',
  description: l10n.integrationGeminiDesc,
  fields: [
    ConfigField(
      helperText: l10n.helperGeminiKey,
      label: l10n.geminiLabelModel,
    ),
  ],
)

Adding New Translations

1

Add to English Template

Edit lib/l10n/app_en.arb and add your new key:
{
  "myNewFeature": "My New Feature",
  "welcomeMessage": "Welcome, {userName}!",
  
  "@welcomeMessage": {
    "placeholders": {
      "userName": {
        "type": "String"
      }
    }
  }
}
2

Add to All Language Files

Add the same keys to all other ARB files:
  • app_es.arb: "myNewFeature": "Mi Nueva Función"
  • app_it.arb: "myNewFeature": "La Mia Nuova Funzione"
  • app_pt.arb: "myNewFeature": "Meu Novo Recurso"
  • app_fr.arb: "myNewFeature": "Ma Nouvelle Fonctionnalité"
  • app_de.arb: "myNewFeature": "Meine Neue Funktion"
3

Generate Code

Run Flutter’s code generator:
flutter gen-l10n
Or simply build/run the app:
flutter run
This generates lib/l10n/app_localizations.dart and language-specific classes.
4

Use in Code

Text(AppLocalizations.of(context)!.myNewFeature)
Text(AppLocalizations.of(context)!.welcomeMessage(user.name))

Adding a New Language

1

Update l10n.yaml

Add the new locale code to supported-locales:
supported-locales:
  - en
  - es
  - it
  - pt
  - fr
  - de
  - ja  # Japanese (new)
2

Create ARB File

Create lib/l10n/app_ja.arb:
{
  "@@locale": "ja",
  "appTitle": "Invenicum インベントリ",
  "dashboard": "ダッシュボード",
  "settings": "設定",
  // ... translate all keys from app_en.arb
}
3

Update Language Dropdown

Add the language option to the language selection UI in your settings screen.
4

Generate and Test

flutter gen-l10n
flutter run

RTL (Right-to-Left) Support

RTL languages like Arabic or Hebrew are not currently implemented in Invenicum. The framework supports RTL, but the app has not been tested with RTL locales.
To add RTL support in the future:
  1. Add RTL locale to l10n.yaml (e.g., ar for Arabic)
  2. Create ARB file with translations
  3. Flutter automatically handles text direction based on locale
  4. Test all UI layouts for RTL compatibility
// Flutter automatically sets text direction
Text('مرحبا')  // Displays right-to-left for Arabic locale

Best Practices

Use descriptive keys: Instead of text1, use dashboardTitle or errorLoadingData.
Keep translations in sync: When adding a new key, update all language files to avoid missing translations.
Avoid hardcoded strings: Always use AppLocalizations for user-facing text, even for placeholders and error messages.
Missing translations: The missing_translations.txt file will list any keys missing from language files after code generation.

Generated Files

Do not edit these files manually (they’re auto-generated):
  • lib/l10n/app_localizations.dart - Base class
  • lib/l10n/app_localizations_en.dart - English
  • lib/l10n/app_localizations_es.dart - Spanish
  • lib/l10n/app_localizations_it.dart - Italian
  • lib/l10n/app_localizations_pt.dart - Portuguese
  • lib/l10n/app_localizations_fr.dart - French
  • lib/l10n/app_localizations_de.dart - German

Build docs developers (and LLMs) love