¿Cómo muestro nombres de idiomas como English, Español, 日本語?
Usa Intl.DisplayNames para mostrar nombres de idiomas en sus escrituras nativas para selectores de idioma e interfaces internacionalizadas.
Introducción
Cuando construyes un selector de idioma o muestras una lista de idiomas disponibles, necesitas mostrar cada nombre de idioma de una manera que los usuarios puedan reconocer. Un hablante de francés busca "Français", un hablante de español busca "Español", y un hablante de japonés busca "日本語". Los usuarios identifican su idioma por su escritura y ortografía nativas.
Codificar estas traducciones de forma fija no escala. Necesitarías mantener traducciones de cada nombre de idioma a todos los demás idiomas. La API Intl.DisplayNames resuelve este problema proporcionando nombres estandarizados y adaptados a la configuración regional para idiomas, países, escrituras y monedas.
El problema de codificar nombres de idiomas de forma fija
Puedes crear un selector de idioma codificando nombres de idiomas de forma fija en un objeto.
const languageNames = {
en: "English",
es: "Spanish",
fr: "French",
de: "German",
ja: "Japanese"
};
console.log(languageNames.en);
// "English"
Este enfoque tiene tres problemas. Primero, estos nombres solo funcionan para hablantes de inglés. Segundo, los usuarios no pueden reconocer su idioma cuando aparece en inglés. Un usuario japonés que busca su idioma busca caracteres japoneses, no la palabra "Japanese". Tercero, necesitas mantener manualmente traducciones de cada idioma a todos los demás idiomas.
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
};
Esto rápidamente se vuelve imposible de mantener. Necesitas una mejor solución.
Usar Intl.DisplayNames para obtener nombres de idiomas
El constructor Intl.DisplayNames crea un formateador que convierte códigos de idioma en nombres legibles para humanos. Especificas una configuración regional y el tipo de nombres que deseas mostrar.
const names = new Intl.DisplayNames(["en"], { type: "language" });
console.log(names.of("en"));
// "English"
El primer argumento es un array de identificadores de configuración regional. El segundo argumento es un objeto de opciones donde type: "language" indica al formateador que deseas nombres de idiomas. El método of() toma un código de idioma y devuelve su nombre.
Puedes obtener nombres en cualquier idioma cambiando el locale.
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"
Cada formateador devuelve el nombre del idioma en su locale de visualización. Esto maneja toda la complejidad de mantener las traducciones de nombres de idiomas.
Mostrar nombres de idiomas en su forma nativa
La mejor práctica para los selectores de idioma es mostrar cada idioma en su propia escritura. Los usuarios reconocen su idioma más rápido cuando lo ven escrito en caracteres familiares.
const names = new Intl.DisplayNames(["ja"], { type: "language" });
console.log(names.of("ja"));
// "日本語"
Para obtener el nombre nativo de cada idioma, crea un formateador usando el idioma de destino como locale de visualización.
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"));
// "中文"
Este patrón funciona para cualquier código de idioma. El formateador devuelve el nombre en la escritura y forma que usan los hablantes nativos.
Comprender los formatos de código de idioma
El método of() acepta códigos de idioma en varios formatos. Puedes usar códigos de idioma básicos como "en" o identificadores de locale completos como "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"
El formateador reconoce tanto códigos cortos como identificadores extendidos con subetiquetas de región o escritura. Esto te permite distinguir entre variantes de idioma.
Controlar cómo aparecen los nombres de idiomas
La opción languageDisplay controla el nivel de detalle en los nombres devueltos. Acepta dos valores.
El valor "standard" devuelve nombres completos que incluyen información de dialecto. Este es el valor predeterminado.
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"
El valor "dialect" también devuelve nombres completos con información de dialecto. En la mayoría de los casos, produce el mismo resultado que "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"
Para los selectores de idioma, el formato estándar ayuda a los usuarios a elegir la variante correcta cuando hay múltiples dialectos disponibles.
Obtener nombres de idiomas localizados para la interfaz de usuario
Cuando construyes una página de configuración o un selector de idioma, necesitas mostrar los nombres de idiomas en el idioma de interfaz actual del usuario. Crea un formateador usando el locale del usuario.
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"
Este enfoque muestra nombres descriptivos en el idioma que el usuario comprende. Combínalo con nombres nativos para crear etiquetas híbridas como "日本語 (japonés)" que funcionan tanto para hablantes nativos como para otros.
Construir un selector de idioma con nombres nativos
Un caso de uso común es construir un menú desplegable o lista donde los usuarios seleccionan su idioma preferido. Muestra cada idioma en su forma nativa para que los usuarios puedan encontrar su opción rápidamente.
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);
Esto produce un array de opciones de idioma con nombres nativos.
[
{ 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: "中文" }
]
Puedes renderizar estas opciones en HTML para crear un selector de idioma.
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);
Esto crea un menú desplegable donde cada idioma aparece en su escritura nativa, facilitando que los usuarios identifiquen su idioma.
Crear etiquetas de idioma híbridas
Algunas interfaces muestran tanto el nombre nativo como una traducción en el idioma del usuario. Esto ayuda a usuarios que pueden no reconocer todas las escrituras y también hace la interfaz más accesible.
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)"
Este patrón combina los beneficios de reconocimiento de los nombres nativos con la claridad de las traducciones localizadas.
Gestionar locales de respaldo
El constructor Intl.DisplayNames acepta un array de locales. Si el primer locale no está disponible, el formateador recurre al siguiente locale en el array.
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "language" });
console.log(names.of("fr"));
// "French"
El formateador intenta "xx-XX" primero, que no existe, luego recurre a "en". Esto asegura que tu código funcione incluso cuando el locale solicitado no esté disponible.
Puedes verificar qué locale usa realmente el formateador con el método resolvedOptions().
const names = new Intl.DisplayNames(["xx-XX", "en"], { type: "language" });
console.log(names.resolvedOptions().locale);
// "en"
Esto muestra que el formateador se resolvió a inglés después del respaldo.
Cómo diferentes locales formatean nombres de idiomas
Cada locale tiene sus propias convenciones para los nombres de idiomas. El formateador las aplica automáticamente.
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: "日本語" }
// ]
El formateador maneja automáticamente las mayúsculas, el sistema de escritura y las convenciones lingüísticas de cada idioma.
Compatibilidad con navegadores
La API Intl.DisplayNames está disponible en todos los navegadores modernos. Ha sido compatible desde marzo de 2021 en los principales navegadores, incluidos Chrome, Firefox, Safari y Edge.
Puedes verificar si la API está disponible antes de usarla.
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");
}
Para navegadores más antiguos, necesitas proporcionar una alternativa o usar un polyfill. Una alternativa simple utiliza un mapeo codificado de códigos de idioma a nombres.
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)
Esto garantiza que tu código funcione incluso en navegadores sin compatibilidad con Intl.DisplayNames, aunque pierdes las funciones de localización automática.