# Implement Localization in your Flutter app

1. Add the package **flutter\_localizations** as a dependency to your **pubspec.yaml** file:

```dart
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
```

1.1 Add lang folder under assets and create en.json and es.json and add their paths in asstes in pubspec.yaml

{% tabs %}
{% tab title="en.json" %}

```json
{
    "title": "Localization",
    "hello_world": "Hello, World!",
    "language": "Language",
    "nested": {
        "title": "nested title"
    }
}
```

{% endtab %}

{% tab title="es.json" %}

```json
{
    "title": "ការធ្វើមូលដ្ឋានីយកម្ម",
    "hello_world": "សួស្តី, ពិភពលោក!",
    "language": "ភាសា",
    "nested": {
        "title": "nesto titalia"
    }
}
```

{% endtab %}
{% endtabs %}

2\. In the **main.dart** import the **flutter\_localizations** library and specify **localizationsDelegates** and **supportedLocales** for **MaterialApp**:

```dart
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
          title: 'Flutter App Localization with Provider demo',
          home: // Some home page name,
          localizationsDelegates: [
            // ... app-specific localization delegate[s] here
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            const Locale('en'),
            const Locale('fr'),
            const Locale('es'),
            const Locale('ru'),
          ],
        );
  }
}
```

The elements of the **localizationsDelegates** list are factories that produce collections of localized values.

* **GlobalMaterialLocalizations.delegate** provides localized strings and other values for the Material Components library.
* **GlobalWidgetsLocalizations.delegate** defines the default text direction, either left-to-right or right-to-left, for the widgets library.

3\. Now we will prepare the **app-specific localization delegate**. Let’s create a folder inside of the Lib folder named **localization** and inside of the folder let’s create a file **app\_localization.dart**.

```dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class AppLocalization {
  final Locale locale;
  late Map<String, dynamic> _localizedStrings;

  AppLocalization(this.locale);

  static AppLocalization of(BuildContext context) {
    return Localizations.of<AppLocalization>(context, AppLocalization)!;
  }

  Future<bool> load() async {
    String jsonString =
        await rootBundle.loadString('assets/lang/${locale.languageCode}.json');
    _localizedStrings = json.decode(jsonString);
    return true;
  }

  String translate(String key) {
    return _localizedStrings[key] ?? key;
  }
}

class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalization> {
  const AppLocalizationDelegate();

  @override
  bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);

  @override
  Future<AppLocalization> load(Locale locale) async {
    AppLocalization localizations = AppLocalization(locale);
    await localizations.load();
    return localizations;
  }

  @override
  bool shouldReload(AppLocalizationDelegate old) => false;
}
```

4\. Let’s update main.dart file and add there **app-specific localization delegate**, which we have just created:

```dart
import 'package:flutter_localizations/flutter_localizations.dart';
import 'localization/app_localization.dart';
import 'providers/current_data_provider.dart';
.....

class MyApp extends ConsumerWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // Access the current locale from the languageProvider
    final locale = ref.watch(languageProvider);

    return MaterialApp(
      title: 'Test App',
      locale: locale,
      supportedLocales: const [Locale('en'), Locale('es')],
      localizationsDelegates: const [
        AppLocalizationDelegate(),
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
      ],
```

5.1. For the **drop down list** let’s create a file that will contain a **default list of languages**. In the **lib** folder create a folder named **data**. In this folder create a file named **default\_data.dart**.

```dart
class DefaultData {
  List<String> _languagesListDefault = [
    'English',
    'Español',
  ];

  get languagesListDefault => _languagesListDefault;
}
```

Add a class that will help us simply convert the locales to language names and vice versa. In the **lib** folder create a folder named **helpers**. In this folder create a file named **language\_helper.dart**.

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

class LanguageHelper {
  convertLangNameToLocale(String langNameToConvert) {
    Locale convertedLocale;

    switch (langNameToConvert) {
      case 'English':
        convertedLocale = const Locale('en', 'EN');
        break;
      case 'Español':
        convertedLocale = const Locale('es', 'ES');
        break;
      default:
        convertedLocale = const Locale('en', 'EN');
    }

    return convertedLocale;
  }

  convertLocaleToLangName(String localeToConvert) {
    String langName;

    switch (localeToConvert) {
      case 'en':
        langName = "English";
        break;
      case 'es':
        langName = "Español";
        break;
      default:
        langName = "English";
    }

    return langName;
  }
}
```

6.3. To add a class where the variable of the current language will be stored, in the **lib** folder create a folder named **provider**. In this folder create a file named **current\_data\_provider.dart**.

```dart
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final languageProvider = StateProvider<Locale>((ref) => const Locale('en'));

Locale convertLanguageCodeToLocale(String languageCode) {
  switch (languageCode) {
    case 'ES':
      return const Locale('es');
    default:
      return const Locale('en');
  }
}
```

Create a Language Switcher Widget

```
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../providers/current_data_provider.dart';

class LanguageChanger extends ConsumerWidget {
  final List<String> languages = ["EN", "ES"];

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final currentLocale = ref.watch(languageProvider);
    final currentLanguageCode = currentLocale.languageCode.toUpperCase();

    return DropdownButton<String>(
      value: currentLanguageCode,
      icon: const Icon(Icons.language),
      onChanged: (String? newLanguageCode) {
        if (newLanguageCode != null) {
          ref.read(languageProvider.notifier).state =
              convertLanguageCodeToLocale(newLanguageCode);
        }
      },
      items: languages.map((String language) {
        return DropdownMenuItem<String>(
          value: language,
          child: Text(language),
        );
      }).toList(),
    );
  }
}

// Helper function to convert language code to Locale
Locale convertLanguageCodeToLocale(String languageCode) {
  switch (languageCode) {
    case 'ES':
      return const Locale('es');
    case 'EN':
    default:
      return const Locale('en');
  }
}
```

Now add our LanguageChanger widget to the Home.dart AppBar and use localized 'title'&#x20;

```dart
      appBar: AppBar(
        title: GestureDetector(
          onTap: _onAppBarTapped,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              SvgPicture.asset(
                'assets/icons/logo.svg',
                height: 30,
              ),
              const SizedBox(width: 8),
              Text(
                AppLocalization.of(context).translate('title'),
                style: GoogleFonts.poppins(
                  color: Color(0xFF163B45),
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
        backgroundColor: Colors.white,
        actions: [LanguageChanger()],
      ),
```
