Flutter Localization: Traditional vs Lang Q - A Side-by-Side Comparison
Discover how Lang Q transforms Flutter localization from complex setup to simple implementation
Overview
Flutter localization traditionally requires multiple steps, complex configuration, and manual file management. Lang Q revolutionizes this process with AI-powered translations, automatic plural handling, and zero-configuration workflow. Let's compare both approaches step by step.
📦 Installation
🔧 Traditional Flutter Way
Step 1: Add dependencies
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: any
Step 2: Enable code generation
flutter:
generate: true
Step 3: Create configuration file
# l10n.yaml
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
Result: 3 files to modify, manual configuration required
⚡ Lang Q Way
Single command:
dependencies:
langq_localization: ^1.0.0
flutter pub get
That's it! No additional configuration files needed.
Result: 1 dependency, zero configuration
📝 Add Translated Files
🔧 Traditional Flutter Way
Step 1: Create ARB directory
mkdir lib/l10n
Step 2: Download the translated files for each language and place it in lib/l10n/
folder
// lib/l10n/app_en.arb
{
"hello": "Hello {name}!",
"@hello": {
"description": "A hello message",
"placeholders": {
"name": {
"type": "String",
"example": "World"
}
}
},
"itemCount": "{count, plural, =0{no items} =1{1 item} other{{count} items}}",
"@itemCount": {
"description": "Number of items",
"placeholders": {
"count": {
"type": "num"
}
}
}
}
// lib/l10n/app_es.arb
{
"hello": "¡Hola {name}!",
"itemCount": "{count, plural, =0{ningún artículo} =1{1 artículo} other{{count} artículos}}"
}
Step 3: Generate code
flutter gen-l10n
Result: Manual creation of multiple ARB files, complex JSON syntax, manual plural rules
⚡ Lang Q Way
Step 1: Get API key from Lang Q dashboard
Step 2: Create .env file
LANGQ_API_KEY=your_project_api_key_here
Step 3: Pull translations
dart run langq_localization:pull
That's it! Lang Q automatically:
- Translates to all your target languages
- Handles complex plural rules for each language
- Generates type-safe Dart code
- Creates all necessary files
Result: One command downloads everything, AI handles translations and plurals
⚙️ Configuration
🔧 Traditional Flutter Way
Step 1: Import generated localizations
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
Step 2: Configure MaterialApp
MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''),
Locale('es', ''),
// Add more locales manually
],
home: MyHomePage(),
)
Result: Manual delegate setup, manual locale list maintenance
⚡ Lang Q Way
Step 1: Initialize Lang Q
import 'package:langq_localization/langq.dart';
import 'package:your_app/l10n/generated/langq_locales.g.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await LangQ.init();
runApp(const MyApp());
}
Step 2: Wrap with LangQ.builder
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LangQ.builder(
builder: (context, langq) {
return MaterialApp(
localizationsDelegates: langq.localizationsDelegates,
locale: langq.currentLocale,
supportedLocales: LangQLocales.supportedLocales, // Auto-generated
home: const HomePage(),
);
},
);
}
}
Result: Auto-generated delegates, automatic locale management
💬 Usage
🔧 Traditional Flutter Way
Basic usage:
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final localizations = AppLocalizations.of(context)!;
return Scaffold(
body: Column(
children: [
Text(localizations.hello('World')),
Text(localizations.itemCount(5)),
],
),
);
}
}
Problems:
- Requires context for every translation
- Runtime errors if key doesn't exist
- No compile-time parameter validation
- Verbose
AppLocalizations.of(context)!
calls
⚡ Lang Q Way
Type-safe usage:
import 'package:your_app/l10n/generated/langq_key.g.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
Text(LangQKey.hello(name: 'World')),
Text(LangQKey.itemCount(count: 5)),
],
),
);
}
}
Benefits:
- No context required
- Compile-time error checking
- Required parameters enforced by IDE
- Clean, readable syntax
- Auto-completion support
🌍 Changing Locale
🔧 Traditional Flutter Way
Using State management solution
class LocaleNotifier extends ChangeNotifier {
Locale _locale = Locale('en', 'US');
Locale get locale => _locale;
void setLocale(Locale locale) {
_locale = locale;
notifyListeners();
}
}
// In widget
Provider.of<LocaleNotifier>(context, listen: false)
.setLocale(Locale('es', 'ES'));
Result: Additional dependencies or complex state management
⚡ Lang Q Way
Type-safe locale switching:
// Using generated locale constants
ElevatedButton(
onPressed: () async {
await LangQ.setLocale(LangQLocales.esES);
},
child: Text('Switch to Spanish'),
)
Benefits:
- Built-in locale management
- Type-safe locale constants
- Automatic UI updates
- Persistent across app restarts
📍 Getting Current Locale
🔧 Traditional Flutter Way
Using Localizations widget:
class LocaleDisplay extends StatelessWidget {
@override
Widget build(BuildContext context) {
final currentLocale = Localizations.localeOf(context);
return Text(
'Current language: ${currentLocale.languageCode}',
);
}
}
Result: Context-dependent
⚡ Lang Q Way
Simple access anywhere:
class LocaleDisplay extends StatelessWidget {
@override
Widget build(BuildContext context) {
final currentLocale = LangQ.currentLocale;
return Text(
'Current language: ${currentLocale.languageCode}',
);
}
}
Benefits:
- No context required
- Works anywhere in your app
- Rich locale information
- Type-safe Locale object
🚀 Built-in Formatting Bonus
🔧 Traditional Flutter Way
Manual formatting setup:
import 'package:intl/intl.dart';
class FormattingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
final locale = Localizations.localeOf(context);
final numberFormat = NumberFormat.decimalPattern(locale.toString());
final dateFormat = DateFormat.yMMMd(locale.toString());
final currencyFormat = NumberFormat.simpleCurrency(locale: locale.toString());
return Column(
children: [
Text(numberFormat.format(1234567)),
Text(dateFormat.format(DateTime.now())),
Text(currencyFormat.format(1234.56)),
],
);
}
}
Result: Manual formatter creation, verbose setup
⚡ Lang Q Way
Automatic locale-aware formatting:
class FormattingExample extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
children: [
Text(1234567.numberFormat()), // 1,234,567
Text(DateTime.now().dateFormat()), // Jan 15, 2025
Text(DateTime.now().timeFormat()), // 3:45 PM
Text(0.854.percentageFormat()), // 85.4%
Text(1234.56.currencyFormat()), // $1,234.56
],
);
}
}
Benefits:
- Automatic locale detection
- Extension methods for clean syntax
- No manual formatter creation
- Consistent formatting across app
🎯 Conclusion
While traditional Flutter localization is powerful, it demands significant developer overhead and complex setup. Lang Q transforms this experience by providing:
- 90% faster setup with zero configuration
- AI-powered translations eliminating manual work
- Type-safe generated code preventing runtime errors
- Advanced plural handling working automatically across all languages
- Built-in formatting with locale-aware extensions
Ready to simplify your Flutter localization?
Lang Q: Making Flutter localization so simple that developers can ship global apps without thinking about translation complexity.