flutter
/

GetX Internationalization (i18n): Multi-Language Support

Last Sync: Today

On this page

12
0%
5 min read
Remaining
5 minleft

Click any section to jump — progress syncs automatically

flutter

GetX Internationalization (i18n): Multi-Language Support

Introduction to GetX Internationalization

GetX provides a built‑in internationalization (i18n) system that makes it easy to add multi‑language support to your Flutter app. You can define translations in JSON or Dart maps, switch languages without restarting the app, and even use reactive translation updates. The system integrates seamlessly with GetMaterialApp and works with both stateless and reactive widgets.

Setting Up Translations

To enable translations, create a class that extends Translations and define your language maps. Then pass it to GetMaterialApp.

DARTRead-only
1
import 'package:get/get.dart';

class AppTranslations extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
    'en_US': {
      'title': 'Hello World',
      'welcome': 'Welcome to my app',
      'greeting': 'Hello, %s',
    },
    'es_ES': {
      'title': 'Hola Mundo',
      'welcome': 'Bienvenido a mi aplicación',
      'greeting': 'Hola, %s',
    },
    'fr_FR': {
      'title': 'Bonjour le Monde',
      'welcome': 'Bienvenue dans mon application',
      'greeting': 'Bonjour, %s',
    },
  };
}

// In main.dart
void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      translations: AppTranslations(),
      locale: Locale('en', 'US'), // default locale
      fallbackLocale: Locale('en', 'US'), // fallback if translation missing
      home: HomePage(),
    );
  }
}

Using Translations in UI

Use the .tr extension on any string to get the translated value. It's as simple as that.

DARTRead-only
1
Text('title'.tr) // displays translated title

// With parameters
Text('greeting'.trParams({'name': 'John'})) // replaces %s with John

Switching Locale Dynamically

Change the app language at runtime using Get.updateLocale. The UI will automatically rebuild with the new translations.

DARTRead-only
1
// Switch to Spanish
Get.updateLocale(Locale('es', 'ES'));

// Switch to French
Get.updateLocale(Locale('fr', 'FR'));

Supported Locales & Fallback

You can specify a list of supported locales to restrict the user's choice, and a fallback locale if a key is missing in the current language.

DARTRead-only
1
GetMaterialApp(
  translations: AppTranslations(),
  locale: Locale('en', 'US'),
  fallbackLocale: Locale('en', 'US'),
  supportedLocales: [
    Locale('en', 'US'),
    Locale('es', 'ES'),
    Locale('fr', 'FR'),
  ],
  home: HomePage(),
);

Reactive Translation Updates

When you call Get.updateLocale, all widgets using .tr will automatically rebuild. This is thanks to GetX's reactive system. You don't need any extra code.

Pluralization

GetX supports pluralization using the plural method. Define different translations for singular and plural cases.

DARTRead-only
1
// Translation keys
'en_US': {
  'apples': 'apple',
  'apples_plural': 'apples',
  'apples_count': '%s apple',
  'apples_count_plural': '%s apples',
}

// Usage
int count = 5;
Text(count.plural('apples')) // returns '5 apples'

// Or with custom format
Text(count.plural('apples_count')) // returns '5 apples' (if key with _plural exists)

Using Translation Files (JSON)

For larger apps, you may want to store translations in separate JSON files. You can create a custom Translations class that loads them from assets.

DARTRead-only
1
// assets/locales/en.json
{
  "title": "Hello World",
  "welcome": "Welcome to my app"
}

// Custom translations loader
import 'dart:convert';
import 'package:flutter/services.dart';

class JsonTranslations extends Translations {
  final Map<String, Map<String, String>> _keys = {};

  JsonTranslations() {
    loadTranslations();
  }

  Future<void> loadTranslations() async {
    for (String locale in ['en', 'es', 'fr']) {
      String data = await rootBundle.loadString('assets/locales/$locale.json');
      Map<String, dynamic> decoded = json.decode(data);
      _keys[locale] = decoded.map((key, value) => MapEntry(key, value.toString()));
    }
  }

  @override
  Map<String, Map<String, String>> get keys => _keys;
}

Best Practices

  • Use language codes consistently – en_US, es_ES, etc. This avoids ambiguity.
  • Define a fallback locale – Prevents missing key errors.
  • Use .tr directly in widgets – No need for extra Obx – the system handles updates automatically.
  • Organize translations by feature – Consider splitting large translation maps into modules.
  • Test language switching – Ensure all UI elements update correctly.

Common Mistakes

  • ❌ Forgetting to set translations in GetMaterialApp – Translations won't work. ✅ Always pass the translations instance.
  • ❌ Using hard‑coded strings in widgets – They won't update when language changes. ✅ Always use .tr.
  • ❌ Not providing a fallback locale – Missing keys may cause empty strings. ✅ Set fallbackLocale.
  • ❌ Over‑complicating with reactive state for translations – GetX already updates automatically.

FAQ

  • Q: Can I change the language without restarting the app?
    A: Yes, Get.updateLocale updates the locale and rebuilds the UI instantly.
  • Q: How do I get the current locale?
    A: Use Get.locale or Get.deviceLocale.
  • Q: Does GetX support right‑to‑left (RTL) languages?
    A: Yes, Flutter handles RTL automatically based on the locale. Just ensure your layouts use Directionality or textDirection correctly.
  • Q: Can I use GetX i18n with other GetX features like state management?
    A: Absolutely. The translation system is independent but can be combined with reactive variables (e.g., a language switch controlled by a controller).
  • Q: How do I handle plurals for different languages?
    A: The plural method works with the same base key; you need to define the singular and plural forms in your translation map as shown above.

Conclusion

GetX internationalization provides a simple yet powerful way to make your Flutter app speak multiple languages. With just a few lines of setup, you can support translations, dynamic language switching, and even pluralization. The integration with GetMaterialApp and reactive updates makes it a breeze to implement and maintain.

Try it yourself

import 'package:flutter/material.dart';
import 'package:get/get.dart';

void main() => runApp(MyApp());

class AppTranslations extends Translations {
  @override
  Map<String, Map<String, String>> get keys => {
    'en': {
      'title': 'Multi-Language App',
      'welcome': 'Welcome',
      'greeting': 'Hello, %s',
    },
    'es': {
      'title': 'Aplicación Multilenguaje',
      'welcome': 'Bienvenido',
      'greeting': 'Hola, %s',
    },
    'fr': {
      'title': 'Application Multilingue',
      'welcome': 'Bienvenue',
      'greeting': 'Bonjour, %s',
    },
  };
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'GetX i18n Demo',
      translations: AppTranslations(),
      locale: Locale('en'),
      fallbackLocale: Locale('en'),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('title'.tr)),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('welcome'.tr, style: TextStyle(fontSize: 24)),
            SizedBox(height: 10),
            Text('greeting'.trParams({'name': 'User'})),
            SizedBox(height: 20),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: () => Get.updateLocale(Locale('en')),
                  child: Text('English'),
                ),
                ElevatedButton(
                  onPressed: () => Get.updateLocale(Locale('es')),
                  child: Text('Español'),
                ),
                ElevatedButton(
                  onPressed: () => Get.updateLocale(Locale('fr')),
                  child: Text('Français'),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

Test Your Knowledge

Q1
of 3

Which method is used to change the app language dynamically in GetX?

A
Get.changeLocale
B
Get.setLocale
C
Get.updateLocale
D
Get.locale =
Q2
of 3

How do you display a translated string in a Text widget?

A
Text(translate('key'))
B
Text('key'.tr)
C
Text(Tr('key'))
D
Text(Localization.of(key))
Q3
of 3

What property in GetMaterialApp specifies the language to use if a key is missing?

A
defaultLocale
B
fallbackLocale
C
missingLocale
D
baseLocale

Previous

getx form validation

Next

getx api integration

Related Content

Need help?

Explore our comprehensive docs or start a chat with our tech experts.