---
title: "How do I detect the device language in Flutter?"
description: "Read `WidgetsBinding.instance.platformDispatcher.locales` for the user's preferred languages in order (`.locale` is the first one). Inside the widget tree, `Localizations.localeOf(context)` gives the locale the app actually resolved from `supportedLocales`."
category: flutter
date: 2026-10-09
canonical: https://localizely.com/i18n-questions/flutter/how-do-i-detect-the-device-language-in-flutter/
---

# How do I detect the device language in Flutter?

The device's language settings are exposed by `PlatformDispatcher`: [`locales`](https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/locales.html) is the user's preferred languages in order and [`locale`](https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/locale.html) is the first of them. Read it through the binding rather than the static singleton:

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

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  final dispatcher = WidgetsBinding.instance.platformDispatcher;
  final Locale device = dispatcher.locale;           // de_DE
  final List<Locale> preferred = dispatcher.locales; // [de_DE, en_US]
  print(device.languageCode);    // de
  print(device.countryCode);     // DE
  print(device.toLanguageTag()); // de-DE
  runApp(const MyApp());
}
```

Inside a widget, `View.of(context).platformDispatcher` gives the same object. The old top-level `window` (and `window.locale`) is [deprecated](https://api.flutter.dev/flutter/dart-ui/window.html), and [`PlatformDispatcher.instance`](https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/instance.html) works but is harder to mock in tests. To react when the user changes the system language while the app is running, implement [`WidgetsBindingObserver.didChangeLocales`](https://api.flutter.dev/flutter/widgets/WidgetsBindingObserver/didChangeLocales.html).

`dart:io` also offers [`Platform.localeName`](https://api.flutter.dev/flutter/dart-io/Platform/localeName.html), a string such as `en_US` taken from the operating system. It is a plain string, `dart:io` is not available in web builds, and on Android the value does not change while the app runs, so prefer `PlatformDispatcher` in Flutter code.

The device language is not necessarily the language your app shows. `MaterialApp` matches the preferred locales against [`supportedLocales`](https://api.flutter.dev/flutter/material/MaterialApp/supportedLocales.html) with [`basicLocaleListResolution`](https://api.flutter.dev/flutter/widgets/basicLocaleListResolution.html): full match first, then language plus script, language plus country, language alone, and finally the first entry of `supportedLocales` when nothing matches. With `supportedLocales: [Locale('en'), Locale('de')]` a French device gets English. The result is what [`Localizations.localeOf(context)`](https://api.flutter.dev/flutter/widgets/Localizations/localeOf.html) returns, and it is the value to use for anything the user sees. To change the mapping, pass [`localeListResolutionCallback`](https://api.flutter.dev/flutter/material/MaterialApp/localeListResolutionCallback.html), which receives the whole preference list, or `localeResolutionCallback`, which only gets the first locale:

```dart
MaterialApp(
  supportedLocales: const [Locale('en'), Locale('de')],
  localeListResolutionCallback: (locales, supported) {
    for (final locale in locales ?? const <Locale>[]) {
      if (locale.languageCode == 'de') return const Locale('de');
    }
    return const Locale('en');
  },
)
```

If users pick a language inside the app, set `MaterialApp.locale` instead; see [How to programmatically change the locale in Flutter?](/i18n-questions/flutter/how-to-programmatically-change-the-locale-in-flutter/).

Source: https://localizely.com/i18n-questions/flutter/how-do-i-detect-the-device-language-in-flutter/
