Как отобразить названия стран на разных языках?
Используйте Intl.DisplayNames для преобразования кодов стран в локализованные названия для пользователей со всего мира.
Введение
Когда вы создаёте форму доставки, страницу профиля пользователя или выбор адреса, нужно показывать названия стран. Пользователь видит "France" на английском, "Francia" на испанском, "Frankreich" на немецком и "フランス" на японском. Каждый ожидает увидеть название страны на своём языке.
Ваше приложение хранит коды стран, такие как FR, US или JP в базах данных и API. Эти стандартизированные коды работают во всех системах, но пользователям нужны понятные названия. API Intl.DisplayNames преобразует коды стран в локализованные названия на любом языке — без таблиц переводов и сторонних библиотек.
Что такое коды стран
Страны определяются двухбуквенными кодами по стандарту ISO 3166-1 alpha-2. Каждая страна получает уникальный код, который не меняется во всех языках и системах.
// Common country codes
// US = United States
// GB = Great Britain (United Kingdom)
// FR = France
// DE = Germany (Deutschland)
// JP = Japan
// CN = China
// BR = Brazil
// IN = India
Эти коды встречаются в формах, URL, базах данных и API. Код US всегда означает Соединённые Штаты, независимо от того, работает ли ваше приложение на английском, испанском, японском или любом другом языке. Код — это стабильный идентификатор, а отображаемое название меняется в зависимости от языка пользователя.
Как получить названия стран через Intl.DisplayNames
Конструктор Intl.DisplayNames создаёт форматтер, который преобразует коды стран в их названия. Вы указываете локаль и задаёте тип "region", чтобы получить именно названия стран.
const countryNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(countryNames.of("US"));
// "United States"
console.log(countryNames.of("FR"));
// "France"
console.log(countryNames.of("JP"));
// "Japan"
Первый аргумент — это массив идентификаторов локалей. Опция type: "region" сообщает форматтеру, что нужны названия стран или регионов. Метод of() принимает код страны и возвращает её локализованное название.
Термин «регион» включает страны, территории и географические области. Сюда входят независимые государства, такие как Франция, территории, например Пуэрто-Рико, и специальные регионы, такие как Европейский союз.
Отображение названий стран на разных языках
Один и тот же код страны даёт разные названия на разных языках. Создайте форматтеры для разных локалей, чтобы увидеть, как меняются названия стран.
const englishNames = new Intl.DisplayNames(["en"], { type: "region" });
const spanishNames = new Intl.DisplayNames(["es"], { type: "region" });
const germanNames = new Intl.DisplayNames(["de"], { type: "region" });
const japaneseNames = new Intl.DisplayNames(["ja"], { type: "region" });
console.log(englishNames.of("FR"));
// "France"
console.log(spanishNames.of("FR"));
// "Francia"
console.log(germanNames.of("FR"));
// "Frankreich"
console.log(japaneseNames.of("FR"));
// "フランス"
Каждый форматтер возвращает название страны на языке выбранной локали. Это избавляет от необходимости вручную поддерживать переводы названий стран на разных языках.
Вы можете создать функцию, которая получает названия стран на любом языке.
function getCountryName(countryCode, locale) {
const names = new Intl.DisplayNames([locale], { type: "region" });
return names.of(countryCode);
}
console.log(getCountryName("US", "en"));
// "United States"
console.log(getCountryName("US", "fr"));
// "États-Unis"
console.log(getCountryName("US", "ar"));
// "الولايات المتحدة"
console.log(getCountryName("DE", "en"));
// "Germany"
console.log(getCountryName("DE", "de"));
// "Deutschland"
console.log(getCountryName("DE", "es"));
// "Alemania"
Эта функция работает с любой комбинацией кода страны и локали. Браузер автоматически предоставляет переводы.
Создание селектора страны
Частый кейс — создание выпадающего списка, где пользователь выбирает свою страну. Названия стран должны отображаться на языке пользователя.
function createCountrySelector(locale) {
const countryNames = new Intl.DisplayNames([locale], { type: "region" });
const countries = [
"US", "GB", "CA", "AU", "FR", "DE", "ES", "IT",
"JP", "CN", "KR", "IN", "BR", "MX", "AR", "RU"
];
const select = document.createElement("select");
select.id = "country";
select.name = "country";
const placeholder = document.createElement("option");
placeholder.value = "";
placeholder.textContent = "Select a country";
select.appendChild(placeholder);
countries.forEach((code) => {
const option = document.createElement("option");
option.value = code;
option.textContent = countryNames.of(code);
select.appendChild(option);
});
return select;
}
const selector = createCountrySelector("en");
document.body.appendChild(selector);
Это создаёт выпадающий список с названиями стран на английском. Измените локаль на "es", и та же функция покажет страны на испанском. Если выбрать "ja", названия появятся на японском.
Вы можете сделать так, чтобы селектор реагировал на язык браузера пользователя.
function createLocalizedCountrySelector() {
const userLocale = navigator.language;
return createCountrySelector(userLocale);
}
const selector = createLocalizedCountrySelector();
document.body.appendChild(selector);
Селектор автоматически показывает названия стран на предпочитаемом языке пользователя, основываясь на настройках браузера.
Получение всех доступных стран
Метод Intl.supportedValuesOf() возвращает массив всех поддерживаемых кодов стран. Это избавляет от необходимости поддерживать жёстко заданный список.
const allCountries = Intl.supportedValuesOf("region");
console.log(allCountries.length);
// 249 (approximate count as of 2025)
console.log(allCountries.slice(0, 10));
// ["AC", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AO", "AQ"]
Метод возвращает коды в алфавитном порядке по коду, а не по названию страны. Если нужен алфавитный порядок по локализованным названиям, сортируйте по ним.
function getSortedCountries(locale) {
const countryNames = new Intl.DisplayNames([locale], { type: "region" });
const allCountries = Intl.supportedValuesOf("region");
return allCountries
.map((code) => ({
code,
name: countryNames.of(code)
}))
.sort((a, b) => a.name.localeCompare(b.name, locale));
}
const sortedEnglish = getSortedCountries("en");
console.log(sortedEnglish.slice(0, 5));
// [
// { code: "AF", name: "Afghanistan" },
// { code: "AX", name: "Åland Islands" },
// { code: "AL", name: "Albania" },
// { code: "DZ", name: "Algeria" },
// { code: "AS", name: "American Samoa" }
// ]
const sortedSpanish = getSortedCountries("es");
console.log(sortedSpanish.slice(0, 5));
// [
// { code: "AF", name: "Afganistán" },
// { code: "AL", name: "Albania" },
// { code: "DE", name: "Alemania" },
// { code: "AD", name: "Andorra" },
// { code: "AO", name: "Angola" }
// ]
Порядок сортировки отличается в разных языках, потому что названия стран сортируются по-разному в зависимости от алфавита и правил колlation.
Как создать удобный селектор стран
Объедините Intl.supportedValuesOf() с Intl.DisplayNames, чтобы сделать селектор со всеми доступными странами.
function createComprehensiveCountrySelector(locale) {
const countryNames = new Intl.DisplayNames([locale], { type: "region" });
const allCountries = Intl.supportedValuesOf("region");
const sortedCountries = allCountries
.map((code) => ({
code,
name: countryNames.of(code)
}))
.sort((a, b) => a.name.localeCompare(b.name, locale));
const select = document.createElement("select");
select.id = "country";
select.name = "country";
const placeholder = document.createElement("option");
placeholder.value = "";
placeholder.textContent = "Select a country";
select.appendChild(placeholder);
sortedCountries.forEach(({ code, name }) => {
const option = document.createElement("option");
option.value = code;
option.textContent = name;
select.appendChild(option);
});
return select;
}
const selector = createComprehensiveCountrySelector("en");
document.body.appendChild(selector);
В этом селекторе есть все 249 стран и территорий, поддерживаемых браузером, отсортированные по алфавиту на языке пользователя.
Как обрабатывать некорректные коды стран
Не все двухбуквенные строки — это корректные коды стран. Метод 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("US"));
// "United States"
console.log(withCodeFallback.of("XX"));
// "XX"
console.log(withNoneFallback.of("US"));
// "United States"
console.log(withNoneFallback.of("XX"));
// undefined
Опция fallback: "code" возвращает исходный код, если страна не найдена. Опция fallback: "none" возвращает undefined для некорректных кодов.
Используйте fallback: "none", если нужно явно определять и обрабатывать некорректные коды.
function getValidatedCountryName(code, locale) {
const names = new Intl.DisplayNames([locale], {
type: "region",
fallback: "none"
});
const name = names.of(code);
if (name === undefined) {
return "Unknown country";
}
return name;
}
console.log(getValidatedCountryName("US", "en"));
// "United States"
console.log(getValidatedCountryName("INVALID", "en"));
// "Unknown country"
Этот подход помогает валидировать пользовательский ввод или данные из внешних источников.
Как управлять длиной названия страны через стиль
Опция 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 longNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "long"
});
const shortNames = new Intl.DisplayNames(["en"], {
type: "region",
style: "short"
});
console.log(longNames.of("GB"));
// "United Kingdom"
console.log(shortNames.of("GB"));
// "UK"
console.log(longNames.of("BO"));
// "Bolivia"
console.log(shortNames.of("BO"));
// "Bolivia"
Используйте стиль long по умолчанию для большинства интерфейсов. Стили short или narrow подойдут, если мало места, например, в мобильной навигации или компактных таблицах.
Отображение названий регионов для территорий
Стандарт ISO 3166-1 включает территории, зависимые и специальные области помимо независимых стран. API Intl.DisplayNames также поддерживает их.
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("PR"));
// "Puerto Rico"
console.log(regionNames.of("GU"));
// "Guam"
console.log(regionNames.of("HK"));
// "Hong Kong"
console.log(regionNames.of("MQ"));
// "Martinique"
console.log(regionNames.of("GF"));
// "French Guiana"
Эти коды работают так же, как и коды стран. Ваше приложение может обрабатывать их одинаково, а браузер будет предоставлять соответствующие локализованные названия.
Использование числовых кодов регионов
Стандарт ISO 3166-1 также определяет числовые коды. API Intl.DisplayNames принимает числовые коды регионов ООН M.49 в дополнение к двухбуквенным кодам.
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("840"));
// "United States"
console.log(regionNames.of("250"));
// "France"
console.log(regionNames.of("392"));
// "Japan"
Числовые коды также обозначают более крупные географические регионы.
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
console.log(regionNames.of("150"));
// "Europe"
console.log(regionNames.of("019"));
// "Americas"
console.log(regionNames.of("142"));
// "Asia"
console.log(regionNames.of("002"));
// "Africa"
console.log(regionNames.of("009"));
// "Oceania"
Эти коды работают во всех языках.
const englishRegions = new Intl.DisplayNames(["en"], { type: "region" });
const spanishRegions = new Intl.DisplayNames(["es"], { type: "region" });
console.log(englishRegions.of("150"));
// "Europe"
console.log(spanishRegions.of("150"));
// "Europa"
Используйте числовые коды, если нужно избежать проблем с кодировкой символов или работать с системами, использующими коды ООН M.49.
Кэширование экземпляров DisplayNames для производительности
Создание экземпляров Intl.DisplayNames требует минимальных ресурсов, но приложения, которые конвертируют много кодов стран, могут выиграть от кэширования форматтеров.
const displayNamesCache = new Map();
function getDisplayNames(locale, type) {
const key = `${locale}-${type}`;
if (!displayNamesCache.has(key)) {
displayNamesCache.set(
key,
new Intl.DisplayNames([locale], { type })
);
}
return displayNamesCache.get(key);
}
function getCountryName(code, locale) {
const formatter = getDisplayNames(locale, "region");
return formatter.of(code);
}
console.log(getCountryName("US", "en"));
// "United States"
console.log(getCountryName("FR", "en"));
// "France"
console.log(getCountryName("US", "es"));
// "Estados Unidos"
Кэш хранит форматтеры по ключу локали и типа. Повторные вызовы используют уже существующие форматтеры вместо создания новых.
Эта оптимизация особенно важна при отображении больших списков стран или обработке сотен кодов стран в таблицах или грид-сетках.
Обработка резервных локалей
Конструктор Intl.DisplayNames принимает массив локалей. Если первая локаль не поддерживается, браузер переходит к следующей в массиве.
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "region" });
console.log(names.of("US"));
// "United States"
Браузер сначала пробует "xx-XX", которой не существует, затем переходит к "en". Это гарантирует, что ваш код будет работать даже при недоступности запрошенной локали.
Вы можете проверить, какой язык на самом деле использует форматтер.
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "region" });
console.log(names.resolvedOptions().locale);
// "en"
Метод resolvedOptions() возвращает язык, который был выбран форматтером после обработки всех вариантов.
Сравнение названий стран на разных языках
В разных языках названия стран оформляются по-разному. В одних языках они пишутся с заглавной буквы, в других — нет. В некоторых языках используются артикли, в других — нет.
const english = new Intl.DisplayNames(["en"], { type: "region" });
const french = new Intl.DisplayNames(["fr"], { type: "region" });
const german = new Intl.DisplayNames(["de"], { type: "region" });
console.log(english.of("US"));
// "United States"
console.log(french.of("US"));
// "États-Unis"
console.log(german.of("US"));
// "Vereinigte Staaten"
console.log(english.of("NL"));
// "Netherlands"
console.log(french.of("NL"));
// "Pays-Bas"
console.log(german.of("NL"));
// "Niederlande"
Форматтер автоматически учитывает все эти языковые особенности. Вам не нужно знать грамматические правила для каждого языка.
Поддержка браузеров
API Intl.DisplayNames с type: "region" доступен во всех современных браузерах. Он поддерживается с 2021 года во всех основных браузерах, включая Chrome, Firefox, Safari и Edge.
Современные приложения могут использовать этот API без полифиллов и запасных решений. Браузер сам хранит данные о названиях стран и обновляет их по мере изменений стран и территорий.
Вы можете проверить доступность API перед его использованием.
if (typeof Intl.DisplayNames !== "undefined") {
const names = new Intl.DisplayNames(["en"], { type: "region" });
console.log(names.of("US"));
} else {
console.log("Intl.DisplayNames is not supported");
}
Для приложений, поддерживающих старые браузеры, используйте запасной вариант — статическую таблицу соответствия названий стран.
function getCountryName(code, locale) {
if (typeof Intl.DisplayNames !== "undefined") {
const names = new Intl.DisplayNames([locale], { type: "region" });
return names.of(code);
}
const fallbackNames = {
US: "United States",
GB: "United Kingdom",
FR: "France",
DE: "Germany",
JP: "Japan"
};
return fallbackNames[code] || code;
}
console.log(getCountryName("US", "en"));
// "United States"
Так вы обеспечите работу приложения во всех браузерах, хотя в старых браузерах не будет автоматической локализации.