Cómo construir identificadores de configuración regional a partir de componentes
Construye identificadores de configuración regional combinando códigos de idioma, script y región en JavaScript
Introducción
Los identificadores de configuración regional como en-US o zh-Hans-CN codifican información sobre idioma, sistema de escritura y región. A veces necesitas construir estos identificadores de forma programática en lugar de usar una cadena fija. Por ejemplo, podrías permitir que los usuarios seleccionen su idioma y región por separado, y luego combinarlos en un identificador de configuración regional válido.
El constructor Intl.Locale de JavaScript te permite construir identificadores de configuración regional a partir de componentes individuales. Puedes especificar idioma, script y región como parámetros separados, y el constructor los ensambla en un identificador con el formato adecuado.
Esta guía explica cómo construir identificadores de configuración regional a partir de componentes, cuándo usar este enfoque y cómo manejar casos especiales.
Comprender los componentes del identificador de configuración regional
Los identificadores de configuración regional constan de componentes separados por guiones. Cada componente representa un aspecto diferente de las preferencias culturales.
El código de idioma especifica qué idioma usar. Utiliza dos o tres letras minúsculas de ISO 639:
enpara inglésespara españolfrpara francészhpara chinoarpara árabe
El código de script especifica el sistema de escritura. Utiliza cuatro letras con la primera letra en mayúscula, de ISO 15924:
Hanspara caracteres chinos simplificadosHantpara caracteres chinos tradicionalesCyrlpara escritura cirílicaLatnpara escritura latina
El código de región especifica el área geográfica. Utiliza dos letras mayúsculas de ISO 3166-1 o tres dígitos de UN M.49:
USpara Estados UnidosGBpara Reino UnidoCNpara ChinaMXpara México
Estos componentes se combinan en un orden específico: idioma, luego escritura, luego región. Por ejemplo, zh-Hans-CN significa idioma chino, escritura simplificada, región China.
Creación de locales con solo idioma y región
El escenario más común es combinar códigos de idioma y región. La mayoría de las aplicaciones no necesitan especificar la escritura porque cada idioma tiene una escritura predeterminada.
Puedes construir un locale pasando el código de idioma como primer argumento y un objeto de opciones con la región:
const locale = new Intl.Locale("en", {
region: "US"
});
console.log(locale.toString());
// Output: "en-US"
Esto crea un identificador de locale para inglés americano.
Puedes crear diferentes variantes regionales del mismo idioma:
const usEnglish = new Intl.Locale("en", { region: "US" });
const britishEnglish = new Intl.Locale("en", { region: "GB" });
const canadianEnglish = new Intl.Locale("en", { region: "CA" });
console.log(usEnglish.toString()); // "en-US"
console.log(britishEnglish.toString()); // "en-GB"
console.log(canadianEnglish.toString()); // "en-CA"
Cada variante usa el mismo idioma pero diferentes convenciones de formato regional.
Creación de locales con idioma, escritura y región
Algunos idiomas requieren códigos de escritura explícitos. El chino, el serbio y algunos otros idiomas usan múltiples sistemas de escritura. Debes especificar la escritura para evitar ambigüedades.
Puedes agregar el componente de escritura al objeto de opciones:
const simplifiedChinese = new Intl.Locale("zh", {
script: "Hans",
region: "CN"
});
console.log(simplifiedChinese.toString());
// Output: "zh-Hans-CN"
Esto crea un locale para chino simplificado tal como se usa en China.
El chino tradicional usa una escritura y región diferentes:
const traditionalChinese = new Intl.Locale("zh", {
script: "Hant",
region: "TW"
});
console.log(traditionalChinese.toString());
// Output: "zh-Hant-TW"
El código de escritura distingue entre los dos sistemas de escritura.
El serbio usa tanto escritura cirílica como latina. Necesitas especificar qué escritura usar:
const serbianCyrillic = new Intl.Locale("sr", {
script: "Cyrl",
region: "RS"
});
const serbianLatin = new Intl.Locale("sr", {
script: "Latn",
region: "RS"
});
console.log(serbianCyrillic.toString()); // "sr-Cyrl-RS"
console.log(serbianLatin.toString()); // "sr-Latn-RS"
Ambos locales usan el idioma serbio en Serbia, pero con diferentes sistemas de escritura.
Creación de locales a partir de selecciones del usuario
Las interfaces de usuario a menudo permiten a los usuarios seleccionar idioma y región por separado. Puedes combinar estas selecciones en un identificador de locale.
Considera un formulario de configuración con dos menús desplegables:
function buildLocaleFromSelections(languageCode, regionCode) {
const locale = new Intl.Locale(languageCode, {
region: regionCode
});
return locale.toString();
}
const userLocale = buildLocaleFromSelections("es", "MX");
console.log(userLocale);
// Output: "es-MX"
Esto crea un identificador de locale a partir de selecciones independientes.
Puede validar las selecciones capturando errores del constructor:
function buildLocaleFromSelections(languageCode, regionCode) {
try {
const locale = new Intl.Locale(languageCode, {
region: regionCode
});
return {
success: true,
locale: locale.toString()
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
const valid = buildLocaleFromSelections("fr", "CA");
console.log(valid);
// Output: { success: true, locale: "fr-CA" }
const invalid = buildLocaleFromSelections("invalid", "XX");
console.log(invalid);
// Output: { success: false, error: "..." }
El constructor lanza un RangeError si algún componente no es válido.
Construcción de locales con componentes opcionales
No todos los locales necesitan todos los componentes. Puede omitir los componentes que no sean necesarios.
Un locale solo de idioma omite región y script:
const locale = new Intl.Locale("fr");
console.log(locale.toString());
// Output: "fr"
Esto representa francés sin especificar una región o script en particular.
Puede incluir componentes condicionalmente según la entrada del usuario:
function buildLocale(language, options = {}) {
const localeOptions = {};
if (options.region) {
localeOptions.region = options.region;
}
if (options.script) {
localeOptions.script = options.script;
}
const locale = new Intl.Locale(language, localeOptions);
return locale.toString();
}
console.log(buildLocale("en"));
// Output: "en"
console.log(buildLocale("en", { region: "US" }));
// Output: "en-US"
console.log(buildLocale("zh", { script: "Hans", region: "CN" }));
// Output: "zh-Hans-CN"
La función construye el identificador de locale válido más simple según la información disponible.
Sobrescritura de componentes en locales existentes
Puede tomar un identificador de locale existente y sobrescribir componentes específicos. Esto es útil cuando necesita cambiar una parte mientras mantiene las demás intactas.
El segundo argumento del constructor sobrescribe componentes del primer argumento:
const baseLocale = new Intl.Locale("en-US");
const withDifferentRegion = new Intl.Locale(baseLocale, {
region: "GB"
});
console.log(withDifferentRegion.toString());
// Output: "en-GB"
El nuevo locale mantiene el idioma pero cambia la región.
Puede sobrescribir múltiples componentes:
const original = new Intl.Locale("zh-Hans-CN");
const modified = new Intl.Locale(original, {
script: "Hant",
region: "TW"
});
console.log(modified.toString());
// Output: "zh-Hant-TW"
Esto cambia tanto el script como la región mientras preserva el idioma.
Adición de preferencias de formato a locales construidos
Más allá del idioma, script y región, los locales pueden incluir preferencias de formato. Estas preferencias controlan cómo aparecen las fechas, números y otros valores.
Puede agregar preferencias de calendario al construir un locale:
const locale = new Intl.Locale("ar", {
region: "SA",
calendar: "islamic"
});
console.log(locale.toString());
// Output: "ar-SA-u-ca-islamic"
console.log(locale.calendar);
// Output: "islamic"
La preferencia de calendario aparece como una extensión Unicode en la cadena del identificador.
Puede especificar múltiples preferencias de formato:
const locale = new Intl.Locale("en", {
region: "US",
calendar: "gregory",
numberingSystem: "latn",
hourCycle: "h12"
});
console.log(locale.toString());
// Output: "en-US-u-ca-gregory-hc-h12-nu-latn"
El constructor ordena las claves de extensión alfabéticamente.
Estas preferencias afectan cómo los formateadores muestran los datos:
const locale = new Intl.Locale("ar", {
region: "EG",
numberingSystem: "arab"
});
const formatter = new Intl.NumberFormat(locale);
console.log(formatter.format(12345));
// Output: "١٢٬٣٤٥" (Arabic-Indic numerals)
La preferencia del sistema de numeración controla qué dígitos aparecen.
Validación de combinaciones de componentes
No todas las combinaciones de idioma, escritura y región son significativas. El constructor acepta cualquier componente sintácticamente válido, pero algunas combinaciones pueden no representar locales reales.
El constructor valida la sintaxis pero no la corrección semántica:
// Syntactically valid but semantically questionable
const locale = new Intl.Locale("en", {
script: "Arab",
region: "JP"
});
console.log(locale.toString());
// Output: "en-Arab-JP"
Esto construye un locale para inglés en escritura árabe en Japón. El identificador es válido según BCP 47, pero no representa un locale del mundo real.
Puedes usar el método maximize() para verificar si un locale coincide con patrones comunes:
const locale = new Intl.Locale("en", { region: "JP" });
const maximized = locale.maximize();
console.log(maximized.toString());
// Output: "en-Latn-JP"
El método añade la escritura más probable para el idioma. Si el resultado coincide con los patrones esperados, la combinación es razonable.
Lectura de componentes desde locales construidos
Después de construir un locale, puedes leer sus componentes como propiedades.
La propiedad language devuelve el código de idioma:
const locale = new Intl.Locale("fr", { region: "CA" });
console.log(locale.language);
// Output: "fr"
La propiedad region devuelve el código de región:
const locale = new Intl.Locale("fr", { region: "CA" });
console.log(locale.region);
// Output: "CA"
La propiedad script devuelve el código de escritura si se especifica:
const locale = new Intl.Locale("zh", {
script: "Hans",
region: "CN"
});
console.log(locale.script);
// Output: "Hans"
Si la escritura no se especifica, la propiedad devuelve undefined:
const locale = new Intl.Locale("en", { region: "US" });
console.log(locale.script);
// Output: undefined
La propiedad baseName devuelve el identificador completo sin extensiones:
const locale = new Intl.Locale("ar", {
region: "SA",
calendar: "islamic",
numberingSystem: "arab"
});
console.log(locale.baseName);
// Output: "ar-SA"
Esto te proporciona la porción idioma-escritura-región sin preferencias de formato.
Convertir identificadores de locale a cadenas
El método toString() devuelve el identificador de locale completo como una cadena:
const locale = new Intl.Locale("es", { region: "MX" });
const identifier = locale.toString();
console.log(identifier);
// Output: "es-MX"
Puedes usar la cadena con otras APIs de Intl:
const locale = new Intl.Locale("de", { region: "DE" });
const formatter = new Intl.NumberFormat(locale.toString());
const price = 1234.56;
console.log(formatter.format(price));
// Output: "1.234,56"
El formateador acepta la representación en cadena.
La mayoría de las APIs de Intl también aceptan objetos de locale directamente:
const locale = new Intl.Locale("de", { region: "DE" });
const formatter = new Intl.NumberFormat(locale);
La API llama a toString() internamente cuando es necesario.
Casos de uso prácticos
Construir identificadores de locale a partir de componentes resuelve varios problemas comunes en aplicaciones internacionalizadas.
Crear selectores de locale
Las interfaces de usuario a menudo permiten a los usuarios elegir el idioma y la región por separado. Combinas las selecciones:
function createLocaleFromPicker(languageSelect, regionSelect) {
const language = languageSelect.value;
const region = regionSelect.value;
const locale = new Intl.Locale(language, { region });
return locale.toString();
}
// User selects "Spanish" and "Mexico"
const selectedLocale = createLocaleFromPicker(
{ value: "es" },
{ value: "MX" }
);
console.log(selectedLocale);
// Output: "es-MX"
Generar variantes de locale
Puedes generar múltiples variantes regionales a partir de un único código de idioma:
function generateRegionalVariants(languageCode, regionCodes) {
return regionCodes.map(regionCode => {
const locale = new Intl.Locale(languageCode, {
region: regionCode
});
return locale.toString();
});
}
const englishVariants = generateRegionalVariants("en", [
"US",
"GB",
"CA",
"AU",
"NZ"
]);
console.log(englishVariants);
// Output: ["en-US", "en-GB", "en-CA", "en-AU", "en-NZ"]
Esto crea una lista de identificadores de locale para diferentes regiones de habla inglesa.
Construir locales a partir de parámetros de URL
Las URLs a menudo codifican las preferencias de locale como parámetros separados. Puedes construir un locale a partir de estos parámetros:
function getLocaleFromURL(url) {
const params = new URL(url).searchParams;
const language = params.get("lang");
const region = params.get("region");
if (!language) {
return null;
}
const options = {};
if (region) {
options.region = region;
}
try {
const locale = new Intl.Locale(language, options);
return locale.toString();
} catch (error) {
return null;
}
}
const locale1 = getLocaleFromURL("https://example.com?lang=fr®ion=CA");
console.log(locale1);
// Output: "fr-CA"
const locale2 = getLocaleFromURL("https://example.com?lang=ja");
console.log(locale2);
// Output: "ja"
Normalizar identificadores de locale
Puedes normalizar identificadores de locale analizándolos y reconstruyéndolos:
function normalizeLocale(identifier) {
try {
const locale = new Intl.Locale(identifier);
return locale.toString();
} catch (error) {
return null;
}
}
console.log(normalizeLocale("EN-us"));
// Output: "en-US"
console.log(normalizeLocale("zh_Hans_CN"));
// Output: null (invalid separator)
El constructor normaliza las mayúsculas y valida la estructura.
Configuración de formateadores con preferencias de usuario
Puedes construir identificadores de configuración regional con preferencias de formato basadas en la configuración del usuario:
function buildFormatterLocale(language, region, preferences) {
const locale = new Intl.Locale(language, {
region,
hourCycle: preferences.use24Hour ? "h23" : "h12",
numberingSystem: preferences.numberingSystem
});
return locale;
}
const userPreferences = {
use24Hour: true,
numberingSystem: "latn"
};
const locale = buildFormatterLocale("fr", "FR", userPreferences);
const timeFormatter = new Intl.DateTimeFormat(locale, {
hour: "numeric",
minute: "numeric"
});
const now = new Date("2025-10-15T14:30:00");
console.log(timeFormatter.format(now));
// Output: "14:30" (24-hour format)
La configuración regional incluye preferencias de formato de la configuración del usuario.
Cuándo construir locales a partir de componentes
Construir locales a partir de componentes es útil en escenarios específicos. Utiliza este enfoque cuando tengas datos de idioma y región separados, al procesar entrada del usuario o al generar variantes de configuración regional de forma programática.
Utiliza una cadena literal para locales fijos:
// Good for fixed locales
const locale = new Intl.Locale("en-US");
Construye a partir de componentes cuando los valores provengan de variables:
// Good for dynamic locales
const locale = new Intl.Locale(userLanguage, {
region: userRegion
});
El constructor valida los componentes y crea un identificador con formato adecuado.
Compatibilidad con navegadores
El constructor Intl.Locale funciona en todos los navegadores modernos. Chrome, Firefox, Safari y Edge admiten el constructor y el objeto de opciones para construir locales a partir de componentes.
Node.js admite Intl.Locale a partir de la versión 12, con compatibilidad completa para todas las opciones del constructor en la versión 14 y posteriores.
Resumen
El constructor Intl.Locale construye identificadores de configuración regional a partir de componentes individuales. Pasas el código de idioma como primer argumento y proporcionas script, región y preferencias de formato en un objeto de opciones.
Conceptos clave:
- Los identificadores de configuración regional constan de componentes de idioma, script y región
- El constructor acepta un objeto de opciones con propiedades
language,scriptyregion - Puedes sobrescribir componentes de una configuración regional existente pasándola como primer argumento
- Las preferencias de formato como
calendaryhourCycleaparecen como extensiones Unicode - El método
toString()devuelve la cadena de identificador completa - Las propiedades como
language,regionyscriptte permiten leer componentes - El constructor valida la sintaxis pero no la corrección semántica
Utiliza este enfoque al construir configuraciones regionales a partir de la entrada del usuario, generar variantes regionales o combinar selecciones separadas de idioma y región. Para configuraciones regionales fijas, utiliza literales de cadena en su lugar.