다른 언어로 국가 이름을 표시하는 방법은 무엇인가요?

Intl.DisplayNames를 사용하여 국가 코드를 국제 사용자를 위한 현지화된 국가 이름으로 변환하세요.

소개

배송 양식, 사용자 프로필 페이지 또는 주소 선택기를 구축할 때 국가 이름을 표시해야 합니다. 사용자는 영어로 "France", 스페인어로 "Francia", 독일어로 "Frankreich", 일본어로 "フランス"를 봅니다. 각 사용자는 자신의 언어로 작성된 국가 이름을 보기를 기대합니다.

애플리케이션은 FR, US, JP와 같은 국가 코드를 데이터베이스와 API에 저장합니다. 이러한 표준화된 코드는 모든 시스템에서 작동하지만, 사용자에게는 사람이 읽을 수 있는 이름이 필요합니다. Intl.DisplayNames API는 번역 테이블을 유지하거나 외부 라이브러리에 의존하지 않고 국가 코드를 모든 언어의 현지화된 국가 이름으로 변환합니다.

국가 코드 이해하기

국가는 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" }
// ]

국가 이름은 각 언어의 알파벳과 정렬 규칙에 따라 다르게 정렬되므로 언어마다 정렬 순서가 다릅니다.

포괄적인 국가 선택기 구축

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 스타일은 기본값이며 전체 국가 이름을 생성합니다. shortnarrow 스타일은 사용 가능한 경우 축약된 형식을 반환합니다. 대부분의 국가에서 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 표준에는 독립 국가 외에도 영토, 속령 및 특수 지역이 포함됩니다. Intl.DisplayNames API는 이러한 항목도 처리합니다.

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 표준은 숫자 코드도 정의합니다. Intl.DisplayNames API는 두 글자 코드 외에도 UN 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"

문자 인코딩 문제를 피하거나 UN 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"

포매터는 이러한 모든 언어적 관례를 자동으로 처리합니다. 각 언어의 문법 규칙을 알 필요가 없습니다.

브라우저 지원

type: "region"를 사용하는 Intl.DisplayNames API는 모든 최신 브라우저에서 사용할 수 있습니다. Chrome, Firefox, Safari, Edge를 포함한 주요 브라우저에서 2021년부터 지원되었습니다.

최신 애플리케이션은 폴리필이나 대체 방법 없이 이 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"

이렇게 하면 구형 브라우저에서는 자동 현지화 기능을 사용할 수 없지만, 모든 브라우저에서 애플리케이션이 작동합니다.