Adding Multi-Language Support to Flutter Apps

As the world becomes more connected, mobile app developers need to ensure that their apps can cater to a global audience. One crucial aspect of this is providing support for multiple languages. In this article, we'll guide you through the process of enabling multi-language support in a Flutter app, allowing you to increase the accessibility of your app to a wider range of users. Let's dive in and learn how to make your app more inclusive!

Configuration

1. Folder and File Setup

Begin by creating the necessary folder and file structure for your Flutter project. The structure should be similar to the following:

Flutter Folder Structure

2. Pubspec.yaml Configuration

Make sure to add flutter_localizations and intl dependencies to your pubspec.yaml file for Flutter's built-in localization support, and intl helps with internationalization.

dependencies:
 flutter:
   sdk: flutter


 flutter_localizations:
   sdk: flutter


 cupertino_icons: ^1.0.2
 intl: ^0.18.1

Add the language assets file to pubspec.yaml as well:

assets:
 - assets/locales/

Create Language Files

Add language-specific JSON files to the assets/locales folder. A few examples include:

en.json

{
 "hello": "Hello",
 "flutter_localization_demo": "Flutter Localization Demo"
}

es.json

{
 "hello": "Hola",
 "flutter_localization_demo": "DemostraciĆ³n de localizaciĆ³n de Flutter"
}

There will be key-value pairs in these JSON files, where the key is a unique identifier and the value is the translated string.

App Localization Logic

The app_localization.dart file handles app localizations, loading the correct language file based on the user's locale and providing a method for string translation.

//Location: i18n/app_locatization.dart
// Importing necessary libraries
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';


// Class for handling app localizations
class AppLocalizations {
 // The locale for which the app is localized
 final Locale locale;
 // Map to hold the localized strings
 Map<String, String> _localizedStrings = {};


 // Constructor
 AppLocalizations(this.locale);


 // Method to get the current instance of AppLocalizations
 static AppLocalizations of(BuildContext context) {
   // Try to get the localization for the current context, if not available, default to English
   return Localizations.of<AppLocalizations>(context, AppLocalizations) ?? AppLocalizations(Locale('en'));
 }


 // Method to load the localized strings
 Future<bool> load() async {
   // Load the localization file from the assets
   String jsonString = await rootBundle.loadString('assets/locales/${locale.languageCode}.json');
   // Decode the JSON
   Map<String, dynamic> jsonMap = json.decode(jsonString);


   // Convert the dynamic values to String and store them in the _localizedStrings map
   _localizedStrings = jsonMap.map((key, value) {
     return MapEntry(key, value.toString());
   });


   // Return true when loading is done
   return true;
 }


 // Method to get a localized string
 String translate(String key) {
   // Return the localized string if it exists, otherwise return a default message
   return _localizedStrings[key] ?? 'Key not found';
 }
}

The class initializes with the given locale, loads the associated language file, and delivers translated strings via a method (translate).

App Localization Delegate

The app_localization_delegate.dart file defines the localization delegate that Flutter uses to manage and load localized strings.

//Location: i18n/app_localization_delegate.dart
// Importing necessary libraries
import 'package:flutter/material.dart';
import 'package:flutter_localization_demo/i18n/app_localization.dart';


// Class for handling localization delegate
class AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {
 // Constructor
 const AppLocalizationsDelegate();


 // Method to check if a locale is supported
 @override
 bool isSupported(Locale locale) {
   // Currently only English and Spanish are supported
   return ['en', 'es'].contains(locale.languageCode);
 }


 // Method to load the localized strings for a locale
 @override
 Future<AppLocalizations> load(Locale locale) {
   // Create an instance of AppLocalizations for the given locale
   AppLocalizations localizations = AppLocalizations(locale);
   // Load the localized strings and return the AppLocalizations instance
   return localizations.load().then((bool _) {
     return localizations;
   });
 }


 // Method to decide if the delegate should be reloaded
 @override
 bool shouldReload(AppLocalizationsDelegate old) => false;
}

It checks if a given locale is supported, loads the localized strings, and ensures that the delegate does not need to be reloaded.

Integration in main.dart

In the main.dart file, initialize the delegates and supported languages to set up localization for the entire app.

// Importing necessary libraries
import 'package:flutter/material.dart';
import 'package:flutter_localization_demo/i18n/AppLocalizationsDelegate.dart';
import 'package:flutter_localization_demo/i18n/app_localization.dart';
import 'package:flutter_localizations/flutter_localizations.dart';


// Entry point of the application
void main() {
 runApp(const MyApp());
}


// Root widget of the application
class MyApp extends StatelessWidget {
 const MyApp({super.key});


 // Build method to describe the part of the user interface represented by this widget.
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     debugShowCheckedModeBanner: false,
     title: 'Flutter Demo',
     theme: ThemeData(
       colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
       useMaterial3: true,
     ),
     // Localization delegates
     localizationsDelegates: [
       AppLocalizationsDelegate(),
       GlobalMaterialLocalizations.delegate,
       GlobalWidgetsLocalizations.delegate,
       GlobalCupertinoLocalizations.delegate,
     ],
     // Supported locales for this app
     supportedLocales: [
       const Locale('en', ''),
       const Locale('es', ''),
     ],
     // Home page of the app
     home: const MyHomePage(),
   );
 }
}


// Home page widget
class MyHomePage extends StatefulWidget {
 const MyHomePage({super.key});


 // Create the mutable state for this widget
 @override
 State<MyHomePage> createState() => _MyHomePageState();
}


// State for the MyHomePage widget
class _MyHomePageState extends State<MyHomePage> {
 // Build method to describe the part of the user interface represented by this widget.
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(
       // Use localized string for the title
       title: Text(AppLocalizations.of(context).translate('flutter_localization_demo'), style: Theme.of(context).textTheme.titleLarge!.apply(color: Colors.white)),
       backgroundColor: Theme.of(context).colorScheme.primary,
     ),
     body: Center(
       child: Column(
         mainAxisAlignment: MainAxisAlignment.center,
         children: <Widget>[
           Text(
             // Use localized string for the text
             AppLocalizations.of(context).translate('hello'),
             style: Theme.of(context).textTheme.titleLarge,
           ),
         ],
       ),
     ),
   );
 }
}

The localizationsDelegates list includes the custom AppLocalizationsDelegate, along with Flutter's default delegates for material, widgets, and Cupertino (iOS-style) localization. The supportedLocales list specifies the languages supported by the app. 

Accessing Translated Text in Code

You can use the following code snippet to access language text keys in Flutter:

AppLocalizations.of(context).translate('key')

Replace the argument inside 'translate' with the desired key to fetch the corresponding translated text.

Testing Multi-Language 

To test the language-switching functionality, follow these steps:

  • Please go to the settings of your mobile device and find the option to change your language and region settings.
  • To change the language of the system from English to Spanish.
  • When you return to the app, you will notice that it now supports the Spanish language.

To ensure that your multi-language support implementation is effective, follow these steps.

Multi-Language Support to Flutter Apps

You can download the source code from the GitHub link provided below.

Source code: https://github.com/socialmad/flutter_localization_demo

Conclusion

Enabling multi-language support in your Flutter app is a crucial step towards providing a better user experience for a diverse audience. The steps outlined above provide an easy way to integrate localization into your app, making it accessible to users worldwide. You can further customize and expand this foundation as per your localization needs. Thank you for reading this article! If you found it helpful, please connect with me on LinkedIn.


Similar Articles