web-locale-kit

Resolves the user's language(s), timezone, UTC offset and text direction from navigator and Intl, with BCP-47 parsing and graceful fallbacks. Everything below is read live from the library running in this page.

$ npm install web-locale-kit

Your environment

Resolved once when the module loaded. offset is in minutes east of UTC. A value shown as null could not be detected here.

readonly version: string;
readonly language: string | null;
get languages(): readonly string[];
readonly fallbacks: readonly string[];
readonly subtags: LocaleSubtags | null;
readonly timezone: string | null;
readonly offset: number;
readonly rtl: boolean;

parse(tag)

Breaks any BCP-47 tag into its subtags. POSIX forms are accepted; anything malformed returns null, which is what keeps bad navigator.languages entries out.

parse(tag: string | null | undefined): LocaleSubtags | null;

interface LocaleSubtags {
    readonly tag: string;
    readonly baseName: string;
    readonly language: string;
    readonly script: string | null;
    readonly region: string | null;
    readonly variants: readonly string[];
    readonly extensions: readonly string[];
}

expand(tag)

The fallback chain, most specific first. Extensions are dropped before the chain is built.

expand(tag: string | null | undefined): readonly string[];

lookup(supported, fallback?)

Picks the best of the locales you actually ship. An exact match wins; failing that a supported tag that merely refines the request is taken, so asking for en accepts en-US rather than skipping to a language ranked lower.

lookup(supported: readonly string[] | null | undefined, fallback?: string | null): string | null;

The second box is the fallback returned when nothing matches.

Overriding detection

languages is settable, and everything derived from it is recomputed. This is what makes the kit usable on a server, where the process locale is not the user's.

set languages(value: readonly string[] | string);

reset(): void;

Shared singleton state — the override applies to every reader, so the panel above updates too. Applying an RTL language also flips this page's direction.