Locale

Locale reports the user's preferred locales and calendar settings.

Import
import { Locale } from '@ng-native/expo';
Inject
inject(Locale)

Both of expo-localization's getters are synchronous, so unlike the rest of the device-state services there is no default to sit at while the platform answers. What makes this worth a service is that the answers change: a user can switch language in Settings and come back, and a date that was formatted correctly a moment ago is then wrong. Locale subscribes to that; nothing else in the package does.

Install

npx expo install expo-localization
import { Locale } from '@ng-native/expo/locale';

The smallest useful example

import { Component, computed, inject } from '@angular/core';
import { Locale } from '@ng-native/expo/locale';

@Component({
  selector: 'app-date',
  template: `<text>{{ formatted() }}</text>`,
})
export class Date {
  private readonly locale = inject(Locale);
  protected readonly formatted = computed(() =>
    new Intl.DateTimeFormat(this.locale.tag()).format(new globalThis.Date()),
  );
}

What it reports

  • locales - every preferred locale, most preferred first, always at least one entry. That ordering is the reason to prefer this over a single locale string: an app that supports the user's second language should use it rather than fall back to English.
  • locale - the first entry of locales, the one to format with. Null before anything is installed.
  • calendars - the user's calendar preferences: calendar, timeZone, uses24hourClock, firstWeekday.
  • rtl - whether the preferred locale reads right to left. This is a layout decision, not a translation one, which is why it is worth a signal of its own rather than folding into locale.
  • tag - the preferred locale's language tag, the string Intl wants. undefined rather than a guess when nothing has been reported yet.

When it updates

expo-localization does not export the listeners its own hooks use internally, and a language or calendar change happens in Settings, outside the app. So Locale re-reads when the app comes back to the foreground, which is exactly when the answer can have changed - a public API (AppState) rather than a path into a build directory.

Without the module installed

locales and calendars are empty arrays, locale is null, rtl is false, tag is undefined.

Reference

Localeservice@ng-native/expo
import { Locale } from '@ng-native/expo';

Signals

locales
Signal<readonly LocaleLike[]>

Most preferred first, always at least one.

calendars
Signal<readonly CalendarLike[]>

locale
Signal<LocaleLike | null>

The one to format with.

rtl
Signal<boolean>

rtl is a layout decision, not a translation one, and is why this is worth a signal.

tag
Signal<string | undefined>

The tag Intl wants. Undefined rather than a guess when nothing has been reported.

Angular components as native iOS and Android views, built and shipped with Expo.

An alpha. MIT licensed. Sponsor its development.

An independent project, not affiliated with or endorsed by Google, the Angular team or Expo. Angular is a trademark of Google LLC.