The device's language settings are exposed by PlatformDispatcher: locales is the user's preferred languages in order and locale is the first of them. Read it through the binding rather than the static singleton:
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, and PlatformDispatcher.instance 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.
dart:io also offers Platform.localeName, 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 with basicLocaleListResolution: 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) returns, and it is the value to use for anything the user sees. To change the mapping, pass localeListResolutionCallback, which receives the whole preference list, or localeResolutionCallback, which only gets the first locale:
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?.
Published Oct 9, 2026 · Markdown version