English, Español, 日本語와 같은 언어 이름을 표시하는 방법은 무엇인가요?
Intl.DisplayNames를 사용하여 언어 선택기 및 국제화된 인터페이스에서 언어 이름을 해당 언어의 고유 문자로 표시하세요.
소개
언어 선택기를 구축하거나 사용 가능한 언어 목록을 표시할 때, 사용자가 인식할 수 있는 방식으로 각 언어 이름을 표시해야 합니다. 프랑스어 사용자는 "Français"를 찾고, 스페인어 사용자는 "Español"을 찾으며, 일본어 사용자는 "日本語"를 찾습니다. 사용자는 고유 문자와 철자로 자신의 언어를 식별합니다.
이러한 번역을 하드코딩하는 것은 확장성이 없습니다. 모든 언어 이름을 다른 모든 언어로 번역하여 유지 관리해야 합니다. Intl.DisplayNames API는 언어, 국가, 문자 체계 및 통화에 대한 표준화되고 로케일을 인식하는 이름을 제공하여 이 문제를 해결합니다.
언어 이름 하드코딩의 문제점
객체에 언어 이름을 하드코딩하여 언어 선택기를 만들 수 있습니다.
const languageNames = {
en: "English",
es: "Spanish",
fr: "French",
de: "German",
ja: "Japanese"
};
console.log(languageNames.en);
// "English"
이 접근 방식에는 세 가지 문제가 있습니다. 첫째, 이러한 이름은 영어 사용자에게만 작동합니다. 둘째, 사용자는 영어로 표시된 자신의 언어를 인식할 수 없습니다. 일본어 사용자는 자신의 언어를 찾을 때 "Japanese"라는 단어가 아닌 일본어 문자를 찾습니다. 셋째, 모든 언어를 다른 모든 언어로 수동으로 번역하여 유지 관리해야 합니다.
const languageNames = {
en: {
en: "English",
es: "Spanish",
fr: "French",
de: "German",
ja: "Japanese"
},
es: {
en: "Inglés",
es: "Español",
fr: "Francés",
de: "Alemán",
ja: "Japonés"
}
// ... more languages
};
이는 빠르게 유지 관리가 불가능해집니다. 더 나은 솔루션이 필요합니다.
Intl.DisplayNames를 사용하여 언어 이름 가져오기
Intl.DisplayNames 생성자는 언어 코드를 사람이 읽을 수 있는 이름으로 변환하는 포매터를 생성합니다. 로케일과 표시하려는 이름 유형을 지정합니다.
const names = new Intl.DisplayNames(["en"], { type: "language" });
console.log(names.of("en"));
// "English"
첫 번째 인수는 로케일 식별자 배열입니다. 두 번째 인수는 옵션 객체이며, type: "language"는 포매터에 언어 이름을 원한다고 알려줍니다. of() 메서드는 언어 코드를 받아 해당 이름을 반환합니다.
로케일을 변경하여 모든 언어의 이름을 가져올 수 있습니다.
const enNames = new Intl.DisplayNames(["en"], { type: "language" });
const esNames = new Intl.DisplayNames(["es"], { type: "language" });
const frNames = new Intl.DisplayNames(["fr"], { type: "language" });
console.log(enNames.of("es"));
// "Spanish"
console.log(esNames.of("es"));
// "español"
console.log(frNames.of("es"));
// "espagnol"
각 포매터는 표시 로케일에서 언어 이름을 반환합니다. 이는 언어 이름 번역을 유지하는 모든 복잡성을 처리합니다.
언어 이름을 고유 형식으로 표시하기
언어 선택기의 모범 사례는 각 언어를 자체 문자로 표시하는 것입니다. 사용자는 익숙한 문자로 작성된 언어를 볼 때 더 빠르게 인식합니다.
const names = new Intl.DisplayNames(["ja"], { type: "language" });
console.log(names.of("ja"));
// "日本語"
각 언어의 고유 이름을 가져오려면 대상 언어를 표시 로케일로 사용하여 포매터를 생성하세요.
function getNativeName(languageCode) {
const names = new Intl.DisplayNames([languageCode], { type: "language" });
return names.of(languageCode);
}
console.log(getNativeName("en"));
// "English"
console.log(getNativeName("es"));
// "español"
console.log(getNativeName("fr"));
// "français"
console.log(getNativeName("de"));
// "Deutsch"
console.log(getNativeName("ja"));
// "日本語"
console.log(getNativeName("ar"));
// "العربية"
console.log(getNativeName("zh"));
// "中文"
이 패턴은 모든 언어 코드에 적용됩니다. 포매터는 원어민이 사용하는 문자와 형식으로 이름을 반환합니다.
언어 코드 형식 이해하기
of() 메서드는 여러 형식의 언어 코드를 허용합니다. "en"과 같은 기본 언어 코드 또는 "en-US"과 같은 전체 로케일 식별자를 사용할 수 있습니다.
const names = new Intl.DisplayNames(["en"], { type: "language" });
console.log(names.of("en"));
// "English"
console.log(names.of("en-US"));
// "American English"
console.log(names.of("en-GB"));
// "British English"
console.log(names.of("zh"));
// "Chinese"
console.log(names.of("zh-Hans"));
// "Simplified Chinese"
console.log(names.of("zh-Hant"));
// "Traditional Chinese"
포매터는 짧은 코드와 지역 또는 문자 하위 태그가 있는 확장 식별자를 모두 인식합니다. 이를 통해 언어 변형을 구분할 수 있습니다.
언어 이름 표시 방식 제어하기
languageDisplay 옵션은 반환되는 이름의 세부 수준을 제어합니다. 두 가지 값을 허용합니다.
"standard" 값은 방언 정보를 포함하는 전체 이름을 반환합니다. 이것이 기본값입니다.
const names = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "standard"
});
console.log(names.of("en-US"));
// "American English"
console.log(names.of("en-GB"));
// "British English"
console.log(names.of("pt-BR"));
// "Brazilian Portuguese"
console.log(names.of("pt-PT"));
// "European Portuguese"
"dialect" 값도 방언 정보가 포함된 전체 이름을 반환합니다. 대부분의 경우 "standard"와 동일한 출력을 생성합니다.
const names = new Intl.DisplayNames(["en"], {
type: "language",
languageDisplay: "dialect"
});
console.log(names.of("en-US"));
// "American English"
console.log(names.of("pt-BR"));
// "Brazilian Portuguese"
언어 선택기의 경우 표준 형식은 여러 방언을 사용할 수 있을 때 사용자가 올바른 변형을 선택하는 데 도움이 됩니다.
사용자 인터페이스에 맞게 현지화된 언어 이름 가져오기
설정 페이지나 언어 선택기를 구축할 때 사용자의 현재 인터페이스 언어로 언어 이름을 표시해야 합니다. 사용자의 로케일을 사용하여 포매터를 생성하세요.
function getLocalizedLanguageName(languageCode, userLocale) {
const names = new Intl.DisplayNames([userLocale], { type: "language" });
return names.of(languageCode);
}
// User interface is in English
console.log(getLocalizedLanguageName("ja", "en"));
// "Japanese"
// User interface is in French
console.log(getLocalizedLanguageName("ja", "fr"));
// "japonais"
// User interface is in Spanish
console.log(getLocalizedLanguageName("ja", "es"));
// "japonés"
이 접근 방식은 사용자가 이해하는 언어로 설명적인 이름을 표시합니다. 이를 네이티브 이름과 결합하여 "日本語 (Japanese)"와 같은 하이브리드 레이블을 만들면 네이티브 스피커와 다른 사용자 모두에게 효과적입니다.
네이티브 이름으로 언어 선택기 구축하기
일반적인 사용 사례는 사용자가 선호하는 언어를 선택할 수 있는 드롭다운 또는 목록을 구축하는 것입니다. 각 언어를 네이티브 형식으로 표시하면 사용자가 자신의 옵션을 빠르게 찾을 수 있습니다.
const supportedLanguages = ["en", "es", "fr", "de", "ja", "ar", "zh"];
function createLanguageOptions() {
return supportedLanguages.map((code) => {
const names = new Intl.DisplayNames([code], { type: "language" });
const nativeName = names.of(code);
return { code, name: nativeName };
});
}
const options = createLanguageOptions();
console.log(options);
이렇게 하면 네이티브 이름이 포함된 언어 옵션 배열이 생성됩니다.
[
{ code: "en", name: "English" },
{ code: "es", name: "español" },
{ code: "fr", name: "français" },
{ code: "de", name: "Deutsch" },
{ code: "ja", name: "日本語" },
{ code: "ar", name: "العربية" },
{ code: "zh", name: "中文" }
]
이러한 옵션을 HTML로 렌더링하여 언어 선택기를 만들 수 있습니다.
function renderLanguageSelector() {
const options = createLanguageOptions();
const select = document.createElement("select");
select.id = "language-selector";
options.forEach((option) => {
const optionElement = document.createElement("option");
optionElement.value = option.code;
optionElement.textContent = option.name;
select.appendChild(optionElement);
});
return select;
}
const selector = renderLanguageSelector();
document.body.appendChild(selector);
이렇게 하면 각 언어가 네이티브 스크립트로 표시되는 드롭다운이 생성되어 사용자가 자신의 언어를 쉽게 식별할 수 있습니다.
하이브리드 언어 레이블 만들기
일부 인터페이스는 네이티브 이름과 사용자 언어로 된 번역을 모두 표시합니다. 이는 모든 스크립트를 인식하지 못할 수 있는 사용자에게 도움이 되며 인터페이스의 접근성도 향상시킵니다.
function createHybridLabel(languageCode, userLocale) {
const nativeNames = new Intl.DisplayNames([languageCode], {
type: "language"
});
const localizedNames = new Intl.DisplayNames([userLocale], {
type: "language"
});
const nativeName = nativeNames.of(languageCode);
const localizedName = localizedNames.of(languageCode);
if (nativeName === localizedName) {
return nativeName;
}
return `${nativeName} (${localizedName})`;
}
// User interface is in English
console.log(createHybridLabel("ja", "en"));
// "日本語 (Japanese)"
console.log(createHybridLabel("ar", "en"));
// "العربية (Arabic)"
console.log(createHybridLabel("en", "en"));
// "English"
// User interface is in Spanish
console.log(createHybridLabel("ja", "es"));
// "日本語 (japonés)"
이 패턴은 네이티브 이름의 인식 이점과 현지화된 번역의 명확성을 결합합니다.
폴백 로케일 처리하기
Intl.DisplayNames 생성자는 로케일 배열을 허용합니다. 첫 번째 로케일을 사용할 수 없는 경우 포매터는 배열의 다음 로케일로 폴백합니다.
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "language" });
console.log(names.of("fr"));
// "French"
포매터는 먼저 존재하지 않는 "xx-XX"를 시도한 다음 "en"로 대체합니다. 이를 통해 요청한 로케일을 사용할 수 없는 경우에도 코드가 작동합니다.
resolvedOptions() 메서드를 사용하여 포매터가 실제로 사용하는 로케일을 확인할 수 있습니다.
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "language" });
console.log(names.resolvedOptions().locale);
// "en"
이는 폴백 후 포매터가 영어로 해석되었음을 보여줍니다.
다양한 로케일이 언어 이름을 포맷하는 방법
각 로케일은 언어 이름에 대한 고유한 규칙을 가지고 있습니다. 포매터는 이를 자동으로 적용합니다.
const supportedLanguages = ["en", "es", "fr", "de", "ja"];
function showLanguageNamesInLocale(locale) {
const names = new Intl.DisplayNames([locale], { type: "language" });
return supportedLanguages.map((code) => ({
code,
name: names.of(code)
}));
}
console.log(showLanguageNamesInLocale("en"));
// [
// { code: "en", name: "English" },
// { code: "es", name: "Spanish" },
// { code: "fr", name: "French" },
// { code: "de", name: "German" },
// { code: "ja", name: "Japanese" }
// ]
console.log(showLanguageNamesInLocale("es"));
// [
// { code: "en", name: "inglés" },
// { code: "es", name: "español" },
// { code: "fr", name: "francés" },
// { code: "de", name: "alemán" },
// { code: "ja", name: "japonés" }
// ]
console.log(showLanguageNamesInLocale("ja"));
// [
// { code: "en", name: "英語" },
// { code: "es", name: "スペイン語" },
// { code: "fr", name: "フランス語" },
// { code: "de", name: "ドイツ語" },
// { code: "ja", name: "日本語" }
// ]
포매터는 각 언어에 대한 대소문자, 문자 체계 및 언어적 규칙을 자동으로 처리합니다.
브라우저 지원
Intl.DisplayNames API는 모든 최신 브라우저에서 사용할 수 있습니다. 2021년 3월부터 Chrome, Firefox, Safari, Edge를 포함한 주요 브라우저에서 지원되었습니다.
API를 사용하기 전에 사용 가능한지 확인할 수 있습니다.
if (typeof Intl.DisplayNames !== "undefined") {
const names = new Intl.DisplayNames(["en"], { type: "language" });
console.log(names.of("fr"));
} else {
console.log("Intl.DisplayNames is not supported");
}
이전 브라우저의 경우 폴백을 제공하거나 폴리필을 사용해야 합니다. 간단한 폴백은 언어 코드를 이름에 매핑하는 하드코딩된 방식을 사용합니다.
function getLanguageName(code, locale) {
if (typeof Intl.DisplayNames !== "undefined") {
const names = new Intl.DisplayNames([locale], { type: "language" });
return names.of(code);
}
// Fallback for older browsers
const fallbackNames = {
en: "English",
es: "español",
fr: "français",
de: "Deutsch",
ja: "日本語"
};
return fallbackNames[code] || code;
}
console.log(getLanguageName("es", "en"));
// "español" (or "Spanish" if you adjust the fallback for localization)
이를 통해 Intl.DisplayNames 지원이 없는 브라우저에서도 코드가 작동하지만 자동 로컬라이제이션 기능은 사용할 수 없습니다.