国名を異なる言語で表示するにはどうすればよいですか?
Intl.DisplayNamesを使用して、国コードを国際的なユーザー向けにローカライズされた国名に変換します。
はじめに
配送フォーム、ユーザープロフィールページ、または住所セレクターを構築する際、国名を表示する必要があります。ユーザーは英語では「France」、スペイン語では「Francia」、ドイツ語では「Frankreich」、日本語では「フランス」と表示されることを期待します。各ユーザーは自分の言語で書かれた国名を見ることを期待しています。
アプリケーションはデータベースやAPIにFR、US、JPなどの国コードを保存します。これらの標準化されたコードはすべてのシステムで機能しますが、ユーザーには人間が読める名前が必要です。Intl.DisplayNames APIは、翻訳テーブルを維持したり外部ライブラリに依存したりすることなく、国コードをどの言語でもローカライズされた国名に変換します。
国コードについて理解する
国はISO 3166-1 alpha-2規格で定義された2文字のコードで識別されます。各国には、すべての言語とシステムで一定のままである固有のコードが割り当てられています。
// 一般的な国コード
// US = United States(アメリカ合衆国)
// GB = Great Britain(イギリス/英国)
// FR = France(フランス)
// DE = Germany(ドイツ)
// 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 (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.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の国と地域がすべて含まれており、ユーザーの言語でアルファベット順にソートされています。
無効な国コードの処理
すべての2文字の文字列が有効な国コードというわけではありません。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オプションは国名の表示方法を制御します。3つの値で異なる出力長が生成されます。
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スタイルは、利用可能な場合に省略形を返します。ほとんどの国では、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は2文字コードに加えて、国連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"
文字エンコーディングの問題を回避したい場合や、国連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"
これにより、すべてのブラウザでアプリケーションが機能することが保証されますが、古いブラウザでは自動ローカライゼーション機能が失われます。