كيف أعرض أسماء الدول بلغات مختلفة؟
استخدم Intl.DisplayNames لتحويل رموز الدول إلى أسماء دول محلية للمستخدمين الدوليين.
مقدمة
عندما تقوم ببناء نموذج شحن، أو صفحة ملف تعريف مستخدم، أو محدد عناوين، فأنت بحاجة إلى عرض أسماء الدول. يرى المستخدمون "France" بالإنجليزية، و"Francia" بالإسبانية، و"Frankreich" بالألمانية، و"フランス" باليابانية. يتوقع كل مستخدم رؤية أسماء الدول مكتوبة بلغته الخاصة.
يخزن تطبيقك رموز الدول مثل FR، وUS، أو JP في قواعد البيانات وواجهات برمجة التطبيقات. تعمل هذه الرموز الموحدة عبر جميع الأنظمة، لكن المستخدمين بحاجة إلى أسماء يمكن قراءتها. تقوم واجهة برمجة التطبيقات 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، وقواعد البيانات، وواجهات برمجة التطبيقات. يعني الرمز 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 هو الافتراضي وينتج أسماء البلدان الكاملة. يُرجع نمطا 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 مع هذه الحالات أيضاً.
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 رموز المناطق الرقمية 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"
يتعامل المنسق مع جميع هذه الاصطلاحات اللغوية تلقائياً. لا تحتاج إلى معرفة قواعد النحو لكل لغة.
دعم المتصفحات
واجهة برمجة التطبيقات Intl.DisplayNames مع type: "region" متاحة في جميع المتصفحات الحديثة. تم دعمها منذ عام 2021 عبر المتصفحات الرئيسية بما في ذلك Chrome وFirefox وSafari وEdge.
يمكن للتطبيقات الحديثة استخدام واجهة برمجة التطبيقات هذه دون الحاجة إلى polyfills أو بدائل احتياطية. يحتفظ المتصفح ببيانات أسماء الدول ويبقيها محدثة مع تغير الدول والأقاليم.
يمكنك التحقق من توفر واجهة برمجة التطبيقات قبل استخدامها.
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"
يضمن هذا عمل تطبيقك في جميع المتصفحات، على الرغم من أن المتصفحات القديمة تفقد ميزة الترجمة التلقائية.