Локаль определяет правила отображения данных в зависимости от языка, региона и культурных особенностей пользователя. Через локаль форматируются:
В JavaScript работа с локалями реализована через встроенный объект
Intl.
Примеры локалей:
| Локаль | Язык | Регион |
|---|---|---|
en-US |
английский | США |
en-GB |
английский | Великобритания |
ru-RU |
русский | Россия |
kk-KZ |
казахский | Казахстан |
fr-FR |
французский | Франция |
Структура локали обычно выглядит так:
язык-РЕГИОН
Например:
ru-RU
en-US
de-DE
navigator.languageСамый распространённый способ определения языка пользователя —
использование свойства navigator.language.
console.log(navigator.language);
Пример результата:
ru-RU
Значение зависит от языка интерфейса браузера или операционной системы.
navigator.languagesПользователь может указать несколько языков в настройках браузера.
Для получения полного списка используется
navigator.languages.
console.log(navigator.languages);
Пример:
[
"ru-RU",
"ru",
"en-US",
"en"
]
Первый элемент массива считается наиболее предпочтительным.
Получение основной локали:
const locale = navigator.languages[0];
console.log(locale);
language и languages| Свойство | Тип | Назначение |
|---|---|---|
navigator.language |
строка | основная локаль |
navigator.languages |
массив | список предпочитаемых локалей |
Пример:
console.log(navigator.language);
console.log(navigator.languages);
Результат:
en-US
["en-US", "fr", "de"]
Большинство объектов Intl автоматически используют
локаль пользователя, если она не указана явно.
Пример:
const number = 123456.78;
console.log(
new Intl.NumberFormat().format(number)
);
Для пользователя с локалью ru-RU:
123 456,78
Для en-US:
123,456.78
Локаль можно передать первым аргументом.
const number = 123456.78;
console.log(
new Intl.NumberFormat("de-DE").format(number)
);
Результат:
123.456,78
Intl.NumberFormat.supportedLocalesOf()Некоторые окружения могут не поддерживать отдельные локали. Для
проверки используется метод supportedLocalesOf.
const locales = [
"ru-RU",
"fr-FR",
"xx-XX"
];
const supported =
Intl.NumberFormat.supportedLocalesOf(locales);
console.log(supported);
Результат:
["ru-RU", "fr-FR"]
Несуществующая локаль xx-XX была отброшена.
Разные записи локалей могут означать одно и то же. Объект
Intl.Locale позволяет привести их к стандартному виду.
const locale = new Intl.Locale("ru-ru");
console.log(locale.toString());
Результат:
ru-RU
Intl.Localeconst locale = new Intl.Locale("en-US");
console.log(locale);
const locale = new Intl.Locale("ru-RU");
console.log(locale.language);
Результат:
ru
console.log(locale.region);
Результат:
RU
Некоторые языки используют разные системы письма.
const locale =
new Intl.Locale("sr-Cyrl-RS");
console.log(locale.script);
Результат:
Cyrl
Иногда локаль пользователя отсутствует в системе переводов приложения. В таких случаях задаётся запасной язык.
Пример:
const supportedLocales = ["en", "ru"];
const userLocale = navigator.language;
const locale =
supportedLocales.includes(userLocale)
? userLocale
: "en";
console.log(locale);
Недостаток такого подхода — строгое сравнение.
Например:
ru-RU
не совпадает с:
ru
Часто достаточно сравнивать только язык.
const supportedLocales = ["en", "ru"];
const userLocale =
navigator.language.split("-")[0];
const locale =
supportedLocales.includes(userLocale)
? userLocale
: "en";
console.log(locale);
find()const supported = ["en", "ru", "fr"];
const locale =
navigator.languages.find(lang => {
return supported.includes(
lang.split("-")[0]
);
});
console.log(locale);
resolvedOptions()Каждый форматтер Intl может сообщить, какая локаль была
выбрана фактически.
const formatter =
new Intl.DateTimeFormat("ru");
console.log(
formatter.resolvedOptions()
);
Результат:
{
locale: "ru",
calendar: "gregory",
numberingSystem: "latn",
timeZone: "Europe/Moscow",
...
}
Intl.DateTimeFormatconst timeZone =
Intl.DateTimeFormat()
.resolvedOptions()
.timeZone;
console.log(timeZone);
Пример:
Asia/Almaty
Часовой пояс часто используется совместно с локалью.
Часто приложение хранит все региональные параметры в одном объекте.
const userSettings = {
locale: navigator.language,
timeZone:
Intl.DateTimeFormat()
.resolvedOptions()
.timeZone
};
console.log(userSettings);
Пример простой системы локализации:
const messages = {
en: {
greeting: "Hello"
},
ru: {
greeting: "Привет"
}
};
const locale =
navigator.language.split("-")[0];
const message =
messages[locale] || messages.en;
console.log(message.greeting);
Более надёжная схема:
const locales = {
"ru-RU": {
currency: "RUB"
},
"ru": {
currency: "RUB"
},
"en": {
currency: "USD"
}
};
const userLocale = navigator.language;
const config =
locales[userLocale]
|| locales[userLocale.split("-")[0]]
|| locales.en;
console.log(config);
В Node.js локаль также зависит от окружения.
Получение локали:
console.log(
Intl.DateTimeFormat()
.resolvedOptions()
.locale
);
Получение переменных окружения:
console.log(process.env.LANG);
Пример:
ru_RU.UTF-8
Пример:
en-US.Локаль отражает языковые предпочтения, а не географию.
Даже внутри одной страны могут использоваться разные форматы.
Например:
en-US:
12/31/2025en-GB:
31/12/2025Поэтому локаль нельзя использовать как способ определения гражданства или местоположения.
Иногда требуется извлечь только код страны.
const locale = navigator.language;
const region =
locale.split("-")[1];
console.log(region);
Для:
ru-RU
результат:
RU
Некоторые браузеры могут возвращать только язык:
ru
Поэтому код должен учитывать отсутствие региона.
Безопасный вариант:
const locale = navigator.language;
const [language, region] =
locale.split("-");
console.log(language);
console.log(region || "unknown");
Локали нечувствительны к регистру, но стандартный вид желательно сохранять.
const locale1 = "ru-ru";
const locale2 = "RU-RU";
console.log(
locale1.toLowerCase() ===
locale2.toLowerCase()
);
Для приведения к стандартному формату используется:
Intl.getCanonicalLocales()
Пример:
const locales =
Intl.getCanonicalLocales([
"ru-ru",
"EN-us"
]);
console.log(locales);
Результат:
["ru-RU", "en-US"]
const date = new Date();
console.log(
new Intl.DateTimeFormat(
navigator.language
).format(date)
);
const price = 1234567.89;
console.log(
new Intl.NumberFormat(
navigator.language
).format(price)
);
const amount = 5000;
console.log(
new Intl.NumberFormat(
navigator.language,
{
style: "currency",
currency: "USD"
}
).format(amount)
);
Некоторые языки пишутся справа налево.
Пример:
Определение направления:
const locale =
new Intl.Locale("ar-EG");
console.log(locale.textInfo);
Результат:
{
direction: "rtl"
}
const names = [
"яблоко",
"банан",
"абрикос"
];
names.sort(
new Intl.Collator("ru").compare
);
console.log(names);
Результат:
[
"абрикос",
"банан",
"яблоко"
]
const locale =
new Intl.Locale(navigator.language);
console.log({
baseName: locale.baseName,
language: locale.language,
region: locale.region,
script: locale.script
});
function detectLocale() {
const supported = ["en", "ru", "kk"];
const locales = navigator.languages;
for (const locale of locales) {
const language =
locale.split("-")[0];
if (supported.includes(language)) {
return language;
}
}
return "en";
}
const locale = detectLocale();
console.log(locale);
function getUserConfig() {
const locale =
navigator.language;
const timeZone =
Intl.DateTimeFormat()
.resolvedOptions()
.timeZone;
return {
locale,
timeZone
};
}
console.log(
getUserConfig()
);