Jindal India Mobile App - Localization Guide
Overview
The Jindal India Mobile App supports multilingual user interfaces using Flutter's built-in localization framework. The localization system is implemented using Application Resource Bundle (ARB) files, code-generated localization classes, Riverpod state management, and SharedPreferences for language persistence.
This document describes the localization architecture, file structure, implementation flow, and maintenance procedures.
Technology Stack
The localization implementation is based on the following technologies:
Technology | Purpose |
|---|---|
| Provides Flutter's localization infrastructure and delegates |
| Handles message translation, pluralization, and formatting |
| Manages the application's locale state reactively |
| Persists the user's selected language across app sessions |
| Stores translation resources for each supported language |
| Generates strongly typed localization classes from ARB files |
Project Structure
The localization system consists of the following files and directories:
lib/l10n/
Contains:
Translation source files (
app_*.arb)Generated localization files:
app_localizations.dartapp_localizations_en.dartapp_localizations_hi.dartOther language-specific generated classes
lib/localization/locale_provider.dart
Responsible for:
Defining
localeProviderManaging the active locale through
LocaleNotifierMaintaining the list of supported locales
Providing display names for supported languages
lib/config/shared_pref.dart
Responsible for:
Saving the selected locale
Loading the saved locale during application startup
lib/views/home/language_selection_screen.dart
Responsible for:
Displaying available languages
Allowing users to select a preferred language
Displaying language icons
lib/main.dart
Responsible for:
Configuring localization delegates
Registering supported locales
Applying the active locale to
MaterialApp.router
Supported Languages
The application currently supports the following languages:
Language Code | Display Name | Icon Path |
|---|---|---|
| English (Default) |
|
| हिन्दी (Hindi) |
|
| ગુજરાતી (Gujarati) |
|
| বাংলা (Bengali) |
|
| मराठी (Marathi) |
|
| తెలుగు (Telugu) |
|
| தமிழ் (Tamil) |
|
| ଓଡ଼ିଆ (Odia) |
|
| ਪੰਜਾਬੀ (Punjabi) |
|
| ಕನ್ನಡ (Kannada) |
|
| മലയാളം (Malayalam) |
|
| অসমীয়া (Assamese) |
|
Localization Workflow
The following flow illustrates how the application loads, updates, and persists the selected locale:
graph TD
A[Application Startup] --> B[Load Locale from SharedPreferences]
B --> C[Initialize LocaleNotifier]
C --> D[Update localeProvider State]
D --> E[MaterialApp Rebuilds with Active Locale]
F[User Opens Language Selection Screen] --> G[User Selects a Language]
G --> H[LocaleNotifier.setLocale()]
H --> I[Persist Locale in SharedPreferences]
H --> J[Update localeProvider State]
J --> E
Persistence Layer
Save Locale
static const String localeKey = 'app_locale';
static Future<void> saveLocale(String localeCode) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setString(localeKey, localeCode);
}
Load Locale
static Future<String?> loadLocale() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString(localeKey);
}
Locale State Management
The application uses Riverpod's StateNotifierProvider to manage the active locale.
final localeProvider = StateNotifierProvider<LocaleNotifier, Locale>((ref) {
return LocaleNotifier();
});
class LocaleNotifier extends StateNotifier<Locale> {
LocaleNotifier() : super(const Locale('en')) {
_loadLocale();
}
Future<void> _loadLocale() async {
final savedLocale = await SharedPrefsHelper.loadLocale();
if (savedLocale != null) {
state = Locale(savedLocale);
}
}
Future<void> setLocale(Locale locale) async {
if (!L10n.supportedLocales.contains(locale)) {
return;
}
state = locale;
await SharedPrefsHelper.saveLocale(locale.languageCode);
}
}
MaterialApp Configuration
The selected locale is applied to MaterialApp.router.
@override
Widget build(BuildContext context) {
final locale = ref.watch(localeProvider);
return MaterialApp.router(
locale: locale,
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'),
Locale('hi'),
Locale('gu'),
// Additional supported locales
],
);
}
Using Localized Strings
Import Localization Class
import 'package:jindal_india/l10n/app_localizations.dart';
Access Localizations
final l10n = AppLocalizations.of(context)!;
Display Localized Text
Text(l10n.loginScreenTitle)
Working with Dynamic Placeholders
Define Placeholders in ARB File
"insufficientPoints": "You need at least {points} points to place this order. Currently, you have {available} points.",
"@insufficientPoints": {
"placeholders": {
"points": {
"type": "String"
},
"available": {
"type": "String"
}
}
}
Access in Dart
l10n.insufficientPoints(
requiredPointsStr,
availablePointsStr,
);
Adding a New Translation Key
Step 1: Add the key in app_en.arb
"welcomeUser": "Welcome, {name}!",
"@welcomeUser": {
"placeholders": {
"name": {
"type": "String"
}
}
}
Step 2: Add translations in other ARB files
Example (app_hi.arb):
"welcomeUser": "स्वागत है, {name}!"
Step 3: Generate Localization Files
flutter gen-l10n
Note: Since
generate: trueis enabled inpubspec.yaml, localization files are also generated automatically during compilation and hot restart.
Enabling Assamese (as) Locale
Update locale_provider.dart
Add the locale:
Locale('as')
Update language name mapping:
case 'as':
return 'অসমীয়া (Assamese)';
Update main.dart
Add Assamese to supportedLocales:
Locale('as')
Update language_selection_screen.dart
Add icon mapping:
case 'as':
return 'assets/images/assamese_icon.png';
Ensure the icon asset exists or provide a fallback icon.
Adding a New Language
To introduce a completely new language:
Step 1: Create a New ARB File
Example:
lib/l10n/app_ta.arb
Add:
{
"@@locale": "ta",
"loginScreenTitle": "மீண்டும் வருக,"
}
Step 2: Generate Localization Classes
flutter gen-l10n
Step 3: Register the Locale
Update the following files:
main.dart
Add the locale to:
supportedLocales
locale_provider.dart
Add the locale to:
L10n.supportedLocalesL10n.getLanguageName()
language_selection_screen.dart
Add language icon mapping:
_getLanguageIcon(String code)
Best Practices
Always add new translation keys to
app_en.arbfirst.Maintain identical translation keys across all ARB files.
Use placeholders instead of string concatenation.
Run
flutter gen-l10nafter modifying ARB files.Keep language names and icons synchronized with supported locales.
Validate translations before releasing to production.
Prefer descriptive and meaningful translation keys (for example,
loginScreenTitleinstead oftitle1).
Summary
The Jindal India Mobile App localization framework provides:
Reactive language switching using Riverpod
Persistent locale storage using SharedPreferences
Type-safe localization through generated classes
Support for multiple Indian languages
Easy onboarding of new languages with minimal code changes
Centralized translation management through ARB files
This architecture ensures scalability, maintainability, and a consistent multilingual experience across the application.
Written by :- Ajay kumar