Intl.DisplayNames API
Преобразуйте коды языков, регионов, валют и алфавитов в понятные человеку названия
Введение
В вашем приложении есть код страны US, но пользователи видят текст «Соединённые Штаты». У вас есть код языка fr, но в переключателе языков отображается «Французский». У вас есть код валюты EUR, но на странице оплаты показывается «Евро».
Браузеры содержат обширные локализационные данные, чтобы отображать свои интерфейсы на разных языках. API Intl.DisplayNames открывает эти данные для JavaScript, преобразуя стандартные коды в понятные человеку названия, локализованные для любого языка.
Это избавляет от необходимости использовать сторонние библиотеки или собственные таблицы соответствия, которые требуют поддержки и локализации. Браузер сам обрабатывает и данные, и переводы.
Преобразование кодов регионов в названия стран
Самый частый кейс — преобразование ISO-кодов стран в их названия. Создайте экземпляр DisplayNames с нужной локалью и типом, затем вызовите метод of() с кодом страны:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("GB")); // "United Kingdom"
console.log(regionNames.of("JP")); // "Japan"
Первый параметр принимает массив кодов локалей по стандарту BCP 47. Браузер использует первую поддерживаемую локаль из массива. Опция type указывает, какой тип кода вы хотите преобразовать.
Одни и те же коды дают разные результаты при локализации на разные языки:
const englishRegions = new Intl.DisplayNames(["en"], { type: "region" });
const japaneseRegions = new Intl.DisplayNames(["ja"], { type: "region" });
const spanishRegions = new Intl.DisplayNames(["es"], { type: "region" });
console.log(englishRegions.of("FR")); // "France"
console.log(japaneseRegions.of("FR")); // "フランス"
console.log(spanishRegions.of("FR")); // "Francia"
Этот подход подходит для создания селекторов стран, отображения местоположения и любых элементов интерфейса, где нужно преобразовать коды стран в читаемые названия.
Преобразование кодов языков в названия языков
Коды языков работают по тому же принципу, что и коды регионов. Установите type: "language", чтобы преобразовать коды языков в их названия:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("es")); // "Spanish"
console.log(languageNames.of("zh")); // "Chinese"
console.log(languageNames.of("ar")); // "Arabic"
Коды языков могут включать региональные подтипы для обозначения региональных вариантов:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("en-GB")); // "British English"
console.log(languageNames.of("fr-CA")); // "Canadian French"
console.log(languageNames.of("pt-BR")); // "Brazilian Portuguese"
Это преобразует языковые коды в названия, подходящие для языковых переключателей, интерфейсов перевода и выбора языковых предпочтений.
Отображение названий языков на их родном языке
В языковых переключателях часто показывают каждый язык в его собственной системе письма. Создайте отдельный экземпляр DisplayNames для каждого целевого языка:
const english = new Intl.DisplayNames(["en"], { type: "language" });
const french = new Intl.DisplayNames(["fr"], { type: "language" });
const japanese = new Intl.DisplayNames(["ja"], { type: "language" });
const arabic = new Intl.DisplayNames(["ar"], { type: "language" });
console.log(english.of("en")); // "English"
console.log(french.of("fr")); // "français"
console.log(japanese.of("ja")); // "日本語"
console.log(arabic.of("ar")); // "العربية"
Пользователи быстрее узнают свой язык, если он отображается на родном алфавите.
Преобразование кодов валют в названия валют
Коды валют соответствуют стандарту ISO 4217. Установите type: "currency", чтобы преобразовать трёхбуквенные коды валют в их названия:
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
console.log(currencyNames.of("GBP")); // "British Pound"
console.log(currencyNames.of("JPY")); // "Japanese Yen"
Названия валют локализуются в зависимости от языка отображения:
const englishCurrency = new Intl.DisplayNames(["en"], { type: "currency" });
const germanCurrency = new Intl.DisplayNames(["de"], { type: "currency" });
const japaneseCurrency = new Intl.DisplayNames(["ja"], { type: "currency" });
console.log(englishCurrency.of("EUR")); // "Euro"
console.log(germanCurrency.of("EUR")); // "Euro"
console.log(japaneseCurrency.of("EUR")); // "ユーロ"
Этот подход подходит для селекторов валют в процессах оформления заказа, финансовых дашбордах и интерфейсах конвертации валют.
Преобразование кодов письменности в названия письменностей
Коды письменностей используют стандарт ISO 15924. Установите type: "script", чтобы преобразовать четырёхбуквенные коды письменностей в их названия:
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
console.log(scriptNames.of("Cyrl")); // "Cyrillic"
console.log(scriptNames.of("Hans")); // "Simplified Chinese"
console.log(scriptNames.of("Hant")); // "Traditional Chinese"
Названия письменностей встречаются в интерфейсах реже, но становятся актуальными для систем управления многоязычным контентом и языковых переключателей, различающих системы письма.
Преобразование кодов календарей в названия календарей
Календарные системы различаются в разных культурах. Установите type: "calendar", чтобы преобразовать идентификаторы календарей в их названия:
const calendarNames = new Intl.DisplayNames(["en"], { type: "calendar" });
console.log(calendarNames.of("gregory")); // "Gregorian Calendar"
console.log(calendarNames.of("japanese")); // "Japanese Calendar"
console.log(calendarNames.of("buddhist")); // "Buddhist Calendar"
console.log(calendarNames.of("hebrew")); // "Hebrew Calendar"
console.log(calendarNames.of("islamic")); // "Islamic Calendar"
console.log(calendarNames.of("chinese")); // "Chinese Calendar"
Это полезно для приложений для планирования, выбора дат с возможностью выбора календарной системы и интернационализированных календарных интерфейсов.
Преобразование кодов полей даты и времени в их названия
В интерфейсах даты и времени есть поля с подписями, например, год, месяц и день. Установите type: "dateTimeField", чтобы преобразовать идентификаторы полей в локализованные названия:
const dateFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
console.log(dateFields.of("year")); // "year"
console.log(dateFields.of("month")); // "month"
console.log(dateFields.of("day")); // "day"
console.log(dateFields.of("hour")); // "hour"
console.log(dateFields.of("minute")); // "minute"
console.log(dateFields.of("weekday")); // "day of the week"
console.log(dateFields.of("dayPeriod")); // "AM/PM"
console.log(dateFields.of("timeZoneName")); // "time zone"
Эти имена полей локализуются для языка отображения:
const englishFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
const spanishFields = new Intl.DisplayNames(["es"], { type: "dateTimeField" });
const japaneseFields = new Intl.DisplayNames(["ja"], { type: "dateTimeField" });
console.log(englishFields.of("month")); // "month"
console.log(spanishFields.of("month")); // "mes"
console.log(japaneseFields.of("month")); // "月"
Допустимые идентификаторы полей включают era, year, quarter, month, weekOfYear, weekday, day, dayPeriod, hour, minute, second и timeZoneName.
Этот шаблон подходит для создания доступных выборщиков дат, календарей и компонентов выбора времени с правильно локализованными метками.
Управление длиной отображения с помощью опций стиля
Опция style управляет тем, насколько подробным будет вывод. Три значения дают разную длину:
const longNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "long",
});
const shortNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "short",
});
const narrowNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "narrow",
});
console.log(longNames.of("US")); // "United States"
console.log(shortNames.of("US")); // "US"
console.log(narrowNames.of("US")); // "US"
Стиль long (по умолчанию) выводит полное имя. Стили short и narrow дают сокращённые формы, если они доступны, хотя не для всех кодов есть короткие варианты.
Стиль становится особенно важен для названий языков:
const longLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "long",
});
const shortLanguages = new Intl.DisplayNames(["en"], {
type: "language",
style: "short",
});
console.log(longLanguages.of("en-US")); // "American English"
console.log(shortLanguages.of("en-US")); // "US English"
Используйте long для полных меток в формах и подробных интерфейсах. Используйте short или narrow для компактных отображений, например, в мобильной навигации или в элементах интерфейса с ограниченным пространством.
Работа с региональными языковыми вариантами через languageDisplay
Языковые коды с региональными подметками могут отображаться как диалекты или как стандартные названия языков с региональными уточнениями. Опция languageDisplay управляет этим поведением и применяется только если type: "language":
const dialectNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "dialect",
});
const standardNames = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "standard",
});
console.log(dialectNames.of("nl-BE")); // "Flemish"
console.log(standardNames.of("nl-BE")); // "Dutch (Belgium)"
console.log(dialectNames.of("en-AU")); // "Australian English"
console.log(standardNames.of("en-AU")); // "English (Australia)"
Значение dialect (по умолчанию) отображает региональные варианты с их привычными названиями. Значение standard всегда показывает базовый язык с регионом в скобках.
Выбирайте dialect, если у региональных вариантов есть узнаваемые названия. Используйте standard для единообразного формата или если работаете с редкими языковыми-комбинациями регионов.
Управление поведением при некорректных кодах
Метод of() получает коды, для которых может не быть отображаемых имён. Опция fallback определяет, что произойдёт в этом случае:
const withCodeFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "code",
});
const withNoneFallback = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
console.log(withCodeFallback.of("ZZ")); // "ZZ"
console.log(withNoneFallback.of("ZZ")); // undefined
Значение code (по умолчанию) возвращает исходный код, если отображаемое имя отсутствует. Значение none возвращает undefined для нераспознанных кодов.
Используйте code, если всегда нужна строка для отображения, даже если это просто сам код. Используйте none, если нужно обнаруживать некорректные коды и обрабатывать их явно:
const regionNames = new Intl.DisplayNames(["en"], {
type: "region",
fallback: "none",
});
function getRegionName(code) {
const name = regionNames.of(code);
if (name === undefined) {
return "Unknown region";
}
return name;
}
console.log(getRegionName("US")); // "United States"
console.log(getRegionName("INVALID")); // "Unknown region"
Создание компонента выбора страны
API Intl.DisplayNames интегрируется прямо в интерфейсные компоненты. В этом примере создаётся селектор стран, который отображает названия стран на языке пользователя:
function CountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const countries = [
"US",
"GB",
"CA",
"AU",
"FR",
"DE",
"JP",
"CN",
"BR",
"IN",
];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{countries.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
Компонент получает проп locale, который определяет язык отображения. При изменении locale выпадающий список обновляется с переводом названий стран.
Создание компонента переключения языка
Переключатели языков показывают каждый язык в его собственной системе письма. Создайте экземпляр DisplayNames для каждого языка:
function LanguageSwitcher({ currentLocale, onLocaleChange }) {
const languages = [
{ code: "en", name: "English" },
{ code: "es", name: "Español" },
{ code: "fr", name: "Français" },
{ code: "de", name: "Deutsch" },
{ code: "ja", name: "日本語" },
{ code: "zh", name: "中文" },
];
return (
<div>
{languages.map((lang) => {
const displayNames = new Intl.DisplayNames([lang.code], {
type: "language",
});
const nativeName = displayNames.of(lang.code);
return (
<button
key={lang.code}
onClick={() => onLocaleChange(lang.code)}
className={currentLocale === lang.code ? "active" : ""}
>
{nativeName}
</button>
);
})}
</div>
);
}
Каждая кнопка отображает название языка в его собственном алфавите. Пользователь сразу узнаёт свой язык независимо от текущего языка интерфейса.
Создание компонента выбора валюты
Селекторы валют выигрывают от локализованных названий валют. В этом примере создаётся селектор валюты, который адаптируется к языку отображения:
function CurrencySelector({ locale, value, onChange }) {
const currencyNames = new Intl.DisplayNames([locale], { type: "currency" });
const currencies = ["USD", "EUR", "GBP", "JPY", "CNY", "CAD", "AUD"];
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select currency</option>
{currencies.map((code) => (
<option key={code} value={code}>
{code} - {currencyNames.of(code)}
</option>
))}
</select>
);
}
В выпадающем списке отображаются и код валюты, и её локализованное название. Пользователи из разных регионов видят названия валют на своём языке.
Получение всех поддерживаемых значений
Метод Intl.supportedValuesOf() возвращает массивы всех поддерживаемых значений для каждого типа. Это избавляет от необходимости использовать жёстко заданные списки кодов:
const regions = Intl.supportedValuesOf("region");
console.log(regions); // ["AD", "AE", "AF", "AG", "AI", ...]
const languages = Intl.supportedValuesOf("language");
console.log(languages); // ["aa", "ab", "ae", "af", "ak", ...]
const currencies = Intl.supportedValuesOf("currency");
console.log(currencies); // ["AED", "AFN", "ALL", "AMD", ...]
const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars); // ["buddhist", "chinese", "coptic", ...]
Создавайте динамические селекторы, которые автоматически включают все поддерживаемые значения:
function UniversalCountrySelector({ locale, value, onChange }) {
const regionNames = new Intl.DisplayNames([locale], { type: "region" });
const allRegions = Intl.supportedValuesOf("region");
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
<option value="">Select a country</option>
{allRegions.map((code) => (
<option key={code} value={code}>
{regionNames.of(code)}
</option>
))}
</select>
);
}
Этот компонент включает все коды регионов, поддерживаемые браузером, без необходимости поддерживать жёстко заданный список.
Понимание требований к формату кода
Каждый тип ожидает коды в определённом формате. Неправильный формат приводит к использованию запасного варианта вместо отображения имён.
Коды регионов соответствуют ISO 3166-1 alpha-2 (две буквы) или UN M.49 (три цифры):
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States" (ISO 3166-1)
console.log(regionNames.of("001")); // "world" (UN M.49)
console.log(regionNames.of("150")); // "Europe" (UN M.49)
Коды языков соответствуют BCP 47, который объединяет языковые коды ISO 639 с дополнительными регионами и скриптовыми подметками:
const languageNames = new Intl.DisplayNames(["en"], { type: "language" });
console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("zh-Hans")); // "Simplified Chinese"
console.log(languageNames.of("zh-Hans-CN")); // "Simplified Chinese (China)"
Коды валют соответствуют ISO 4217 (три буквы):
const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });
console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
Коды скриптов соответствуют ISO 15924 (четыре буквы, с заглавной первой буквой):
const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });
console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
Сравнение кодов не зависит от регистра, но соблюдение стандартного написания повышает читаемость:
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("us")); // "United States"
console.log(regionNames.of("Us")); // "United States"
Поддержка браузерами и совместимость
API Intl.DisplayNames стало доступно во всех основных браузерах в 2021 году. Современные приложения могут использовать его без polyfill'ов.
Базовое API с типами language, region, script и currency поддерживается везде. Типы calendar и dateTimeField появились в более поздних версиях браузеров, но к 2025 году поддерживаются широко.
При необходимости проверяйте поддержку функций во время выполнения:
if (typeof Intl.DisplayNames !== "undefined") {
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("US"));
} else {
console.log("Intl.DisplayNames not supported");
}
Для приложений, поддерживающих старые браузеры, используйте статические таблицы поиска или сторонние библиотеки, если API недоступно.
Оптимизация производительности с помощью кэширования
Создание экземпляров DisplayNames практически не влияет на производительность, но если приложение конвертирует много кодов, лучше переиспользовать экземпляры:
const cache = new Map();
function getDisplayNames(locale, type) {
const key = `${locale}-${type}`;
if (!cache.has(key)) {
cache.set(key, new Intl.DisplayNames([locale], { type }));
}
return cache.get(key);
}
function getCountryName(locale, code) {
const displayNames = getDisplayNames(locale, "region");
return displayNames.of(code);
}
console.log(getCountryName("en", "US")); // "United States"
console.log(getCountryName("en", "FR")); // "France"
console.log(getCountryName("es", "US")); // "Estados Unidos"
Кэш хранит экземпляры по ключу из локали и типа. При последующих вызовах используются уже созданные экземпляры, а не создаются новые.
Этот подход особенно важен в горячих участках кода, где конвертируются сотни или тысячи кодов, например, при рендеринге больших таблиц с локализованными данными.
Сравнение с альтернативными подходами
До появления API Intl.DisplayNames приложения использовали разные способы для преобразования кодов в имена.
Жёстко заданные таблицы соответствия требовали поддержки и работали только с заранее определёнными языками:
const countryNames = {
US: "United States",
GB: "United Kingdom",
FR: "France",
};
function getCountryName(code) {
return countryNames[code] || code;
}
Этот подход перестаёт работать при добавлении новых языков, потому что для каждого языка нужна отдельная таблица.
Сторонние библиотеки предоставляли данные для локализации, но увеличивали размер бандла:
import countries from "i18n-iso-countries";
import countriesEN from "i18n-iso-countries/langs/en.json";
import countriesES from "i18n-iso-countries/langs/es.json";
countries.registerLocale(countriesEN);
countries.registerLocale(countriesES);
console.log(countries.getName("US", "en")); // "United States"
console.log(countries.getName("US", "es")); // "Estados Unidos"
Библиотеки добавляют килобайты данных в бандл и требуют обновлений при появлении новых стран или изменении названий.
API Intl.DisplayNames решает обе эти проблемы. Данные поддерживаются браузером, всегда актуальны и не увеличивают размер бандла. Поддерживаются все языки, которые поддерживает браузер, без дополнительных загрузок.