Software Engineering & Digital Products for Global Enterprises since 2006
CMMi Level 3SOC 2ISO 27001
Menu
View all services
Staff Augmentation
Embed senior engineers in your team within weeks.
Dedicated Teams
A ring-fenced squad with PM, leads, and engineers.
Build-Operate-Transfer
We hire, run, and transfer the team to you.
Contract-to-Hire
Try the talent. Convert when you're ready.
ForceHQ
Skill testing, interviews and ranking — powered by AI.
RoboRingo
Build, deploy and monitor voice agents without code.
MailGovern
Policy, retention and compliance for enterprise email.
Vishing
Test and train staff against AI-driven voice attacks.
CyberForceHQ
Continuous, adaptive security training for every team.
IDS Load Balancer
Built for Multi Instance InDesign Server, to distribute jobs.
AutoVAPT.ai
AI agent for continuous, automated vulnerability and penetration testing.
Salesforce + InDesign Connector
Bridge Salesforce data into InDesign to design print catalogues at scale.
View all solutions
Banking, Financial Services & Insurance
Cloud, digital and legacy modernisation across financial entities.
Healthcare
Clinical platforms, patient engagement, and connected medical devices.
Pharma & Life Sciences
Trial systems, regulatory data, and field-force enablement.
Professional Services & Education
Workflow automation, learning platforms, and consulting tooling.
Media & Entertainment
AI video processing, OTT platforms, and content workflows.
Technology & SaaS
Product engineering, integrations, and scale for tech companies.
Retail & eCommerce
Shopify, print catalogues, web-to-print, and order automation.
View all industries
Blog
Engineering notes, opinions, and field reports.
Case Studies
How clients shipped — outcomes, stack, lessons.
White Papers
Deep-dives on AI, talent models, and platforms.
Portfolio
Selected work across industries.
View all resources
About Us
Who we are, our story, and what drives us.
Co-Innovation
How we partner to build new products together.
Careers
Open roles and what it's like to work here.
News
Press, announcements, and industry updates.
Leadership
The people steering MetaDesign.
Locations
Gurugram, Brisbane, Detroit and beyond.
Contact Us
Talk to sales, hiring, or partnerships.
Request TalentStart a Project
Mobile Development

Implementing Localization and Internationalization in Flutter Apps

SS
Sukriti Srivastava
Technical Content Lead
December 7, 2024
10 min read
Implementing Localization and Internationalization in Flutter Apps — Mobile Development | MetaDesign Solutions

i18n vs. l10n: Understanding the Foundation Before You Code

Internationalization (i18n) is the architectural process of designing your application so it can support multiple languages and regions without code changes. Localization (l10n) is the process of actually adapting it for a specific language and culture—translating strings, formatting dates, handling plurals, and adjusting layouts for text direction. i18n is done once by developers; l10n is done per locale by translators. In Flutter, the `flutter_localizations` and `intl` packages handle both, but understanding this distinction prevents a common mistake: hardcoding strings first and trying to extract them later, which is far more expensive than internationalizing from the start.

Setting Up Flutter Localization with flutter_localizations

Add `flutter_localizations` and `intl` to your `pubspec.yaml` dependencies. In your `MaterialApp`, configure three properties: `localizationsDelegates` (which includes `AppLocalizations.delegate`, `GlobalMaterialLocalizations.delegate`, `GlobalWidgetsLocalizations.delegate`, and `GlobalCupertinoLocalizations.delegate`), `supportedLocales` (the list of `Locale` objects your app supports, e.g., `Locale('en')`, `Locale('es')`, `Locale('ar')`), and `locale` (optionally, to override the system default). Enable code generation by adding `generate: true` to `pubspec.yaml` and creating an `l10n.yaml` configuration file specifying your ARB directory and output class.

ARB Files: The Industry-Standard Translation Format

ARB (Application Resource Bundle) files are JSON-like files that store localized strings for each locale. Create a template file `app_en.arb` containing your source strings with unique keys: `{ "homeTitle": "Welcome Home", "@homeTitle": { "description": "Title shown on the home screen" } }`. The `@` metadata entries provide context for translators. For each additional locale, create a corresponding file (`app_es.arb`, `app_ar.arb`) with the same keys and translated values. Run `flutter gen-l10n` to generate type-safe Dart classes. Access translated strings in widgets with `AppLocalizations.of(context)!.homeTitle`—fully type-safe with IDE autocompletion.

Handling Pluralization and Gender with ICU Message Syntax

Different languages have vastly different pluralization rules. English has two forms (singular/plural), but Arabic has six, and Polish has four. The ICU Message Format handles this declaratively in ARB files: `"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"`. For gender-dependent text: `"greeting": "{gender, select, male{He joined} female{She joined} other{They joined}}"`. Flutter's code generator produces Dart functions that accept these parameters: `AppLocalizations.of(context)!.itemCount(3)` returns "3 items" in English and the grammatically correct equivalent in every other language, without any `if/else` logic in your widget code.

Supporting Right-to-Left (RTL) Languages: Arabic, Hebrew, and Urdu

RTL languages require the entire UI layout to be mirrored. Flutter handles this automatically when you use `Directionality`-aware widgets. `Row` children reverse order, `Padding` with `EdgeInsetsDirectional.only(start: 16)` applies to the right side in RTL. Replace `left/right` with `start/end` in all layout properties. For custom widgets, wrap with `Directionality(textDirection: TextDirection.rtl, child: ...)` for testing. Key pitfalls: icons with directional meaning (arrows, back buttons) must be mirrored using `Transform.scale(scaleX: -1)`, and `TextAlign.left` must be replaced with `TextAlign.start`. Always test RTL layouts with actual Arabic/Hebrew content, not English in RTL mode, to catch text overflow issues.

Transform Your Publishing Workflow

Our experts can help you build scalable, API-driven publishing systems tailored to your business.

Book a free consultation

Date, Number, and Currency Formatting with the intl Package

Localization extends far beyond string translation. The `intl` package provides `DateFormat`, `NumberFormat`, and `Intl.message` for locale-aware formatting. `DateFormat.yMMMMd('de').format(DateTime.now())` outputs "12. Mai 2025" (German date format). `NumberFormat.currency(locale: 'ja_JP', symbol: '¥').format(1500)` outputs "¥1,500". Always use these formatters instead of manual string concatenation. For measurement units, consider that the US uses Fahrenheit/miles while most countries use Celsius/kilometers. Store all user-facing numeric and date values with their locale context to ensure correct rendering across all supported languages.

Scaling Translations with Crowdin, Lokalise, and CI/CD

For apps supporting 10+ languages, managing ARB files manually becomes unsustainable. Translation management platforms like Crowdin, Lokalise, and Phrase provide web-based interfaces for professional translators, translation memory (reusing previously translated segments), machine translation suggestions, and CI/CD integration that automatically pushes new source strings and pulls completed translations. Configure your CI pipeline to run `flutter gen-l10n` after pulling new translations, ensuring that the generated Dart classes are always in sync with the latest ARB files. This eliminates the error-prone manual process of copying translated strings into files.

Testing Localization: Pseudo-Localization and Visual Regression

Pseudo-localization is a testing technique that transforms English strings into accented versions (e.g., "Welcome" becomes "[ŵéļçömé]") to reveal hardcoded strings, text truncation, and layout issues without needing actual translations. Flutter supports this via custom locale delegates. For comprehensive testing, verify each locale by switching the device language and navigating all screens. Use visual regression testing with tools like Golden Tests to capture screenshots of every screen in every locale and detect layout regressions automatically. An e-learning app that localized to English, Spanish, and Arabic reported a 50% increase in user base from new regional markets.

FAQ

Frequently Asked Questions

Common questions about this topic, answered by our engineering team.

Internationalization (i18n) is the architectural design that enables multi-language support (done once by developers). Localization (l10n) is the actual translation and cultural adaptation for each specific locale (done per language by translators). Flutter's flutter_localizations and intl packages handle both.

ARB (Application Resource Bundle) files are JSON-like files containing localized strings for each locale. Create a template (app_en.arb) with keys and translations, then create per-locale files (app_es.arb, app_ar.arb). Run flutter gen-l10n to generate type-safe Dart classes for accessing strings.

Flutter uses ICU Message Format in ARB files. Define plural rules like "{count, plural, =0{No items} =1{1 item} other{{count} items}}". The code generator produces Dart functions that accept count parameters and return grammatically correct strings for every locale automatically.

Replace left/right with start/end in all layout properties. Use EdgeInsetsDirectional instead of EdgeInsets. Flutter's Row and layout widgets automatically reverse in RTL mode. Mirror directional icons, replace TextAlign.left with TextAlign.start, and test with actual Arabic/Hebrew content.

Translation management platforms like Crowdin, Lokalise, and Phrase provide web interfaces for translators, translation memory, machine translation suggestions, and CI/CD integration. They automate pushing new source strings and pulling completed translations, eliminating manual ARB file management.

Discussion

Join the Conversation

Ready when you are

Let's build something great together.

A 30-minute call with a principal engineer. We'll listen, sketch, and tell you whether we're the right partner — even if the answer is no.

Talk to a strategist
Need help with your project? Let's talk.
Book a call