Intl.DisplayNames API

言語、地域、通貨、文字体系コードを人間が読める名前に変換

はじめに

アプリケーションには国コード US がありますが、ユーザーには「アメリカ合衆国」というテキストが表示されます。言語コード fr がありますが、言語切り替えには「フランス語」と表示されます。通貨コード EUR がありますが、チェックアウトページには「ユーロ」と表示されます。

ブラウザは、異なる言語で独自のインターフェースをレンダリングするために、広範なローカライゼーションデータを保持しています。Intl.DisplayNames APIは、このデータをJavaScriptに公開し、標準化されたコードを任意の言語にローカライズされた人間が読める名前に変換します。

これにより、メンテナンスとローカライゼーションが必要なサードパーティライブラリやカスタムルックアップテーブルが不要になります。ブラウザがデータと翻訳の両方を処理します。

地域コードから国名への変換

最も一般的な使用例は、ISO国コードを国名に変換することです。ロケールとタイプを指定して DisplayNames インスタンスを作成し、国コードを指定して of() メソッドを呼び出します。

const regionNames = new Intl.DisplayNames(["en"], { type: "region" });

console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("GB")); // "United Kingdom"
console.log(regionNames.of("JP")); // "Japan"

最初のパラメータは、BCP 47標準に従ったロケールコードの配列を受け入れます。ブラウザは、配列から最初にサポートされているロケールを使用します。type オプションは、変換するコードの種類を指定します。

同じコードでも、異なる言語にローカライズすると異なる出力が生成されます。

const englishRegions = new Intl.DisplayNames(["en"], { type: "region" });
const japaneseRegions = new Intl.DisplayNames(["ja"], { type: "region" });
const spanishRegions = new Intl.DisplayNames(["es"], { type: "region" });

console.log(englishRegions.of("FR")); // "France"
console.log(japaneseRegions.of("FR")); // "フランス"
console.log(spanishRegions.of("FR")); // "Francia"

このパターンは、国セレクター、場所表示、および国コードを読みやすい名前に変換するあらゆるインターフェース要素の構築に使用できます。

言語コードから言語名への変換

言語コードは地域コードと同じパターンを使用します。type: "language" を設定して、言語コードを言語名に変換します。

const languageNames = new Intl.DisplayNames(["en"], { type: "language" });

console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("es")); // "Spanish"
console.log(languageNames.of("zh")); // "Chinese"
console.log(languageNames.of("ar")); // "Arabic"

言語コードには、地域バリアント用の地域サブタグを含めることができます。

const languageNames = new Intl.DisplayNames(["en"], { type: "language" });

console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("en-GB")); // "British English"
console.log(languageNames.of("fr-CA")); // "Canadian French"
console.log(languageNames.of("pt-BR")); // "Brazilian Portuguese"

これにより、言語コードが言語スイッチャー、翻訳インターフェース、言語設定セレクターに適した名前に変換されます。

各言語を自身の言語で表示する

言語スイッチャーでは、各言語を独自の表記体系で表示することがよくあります。ターゲット言語ごとに個別のDisplayNamesインスタンスを作成します。

const english = new Intl.DisplayNames(["en"], { type: "language" });
const french = new Intl.DisplayNames(["fr"], { type: "language" });
const japanese = new Intl.DisplayNames(["ja"], { type: "language" });
const arabic = new Intl.DisplayNames(["ar"], { type: "language" });

console.log(english.of("en")); // "English"
console.log(french.of("fr")); // "français"
console.log(japanese.of("ja")); // "日本語"
console.log(arabic.of("ar")); // "العربية"

ユーザーは、母国語の文字で表示されると、自分の言語をより素早く認識できます。

通貨コードを通貨名に変換する

通貨コードはISO 4217標準に従います。type: "currency"を設定して、3文字の通貨コードを通貨名に変換します。

const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });

console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"
console.log(currencyNames.of("GBP")); // "British Pound"
console.log(currencyNames.of("JPY")); // "Japanese Yen"

通貨名は表示ロケールに基づいてローカライズされます。

const englishCurrency = new Intl.DisplayNames(["en"], { type: "currency" });
const germanCurrency = new Intl.DisplayNames(["de"], { type: "currency" });
const japaneseCurrency = new Intl.DisplayNames(["ja"], { type: "currency" });

console.log(englishCurrency.of("EUR")); // "Euro"
console.log(germanCurrency.of("EUR")); // "Euro"
console.log(japaneseCurrency.of("EUR")); // "ユーロ"

このパターンは、チェックアウトフローの通貨セレクター、財務ダッシュボード、通貨換算インターフェースで機能します。

スクリプトコードをスクリプト名に変換する

スクリプトコードはISO 15924標準を使用します。type: "script"を設定して、4文字のスクリプトコードをスクリプト名に変換します。

const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });

console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"
console.log(scriptNames.of("Cyrl")); // "Cyrillic"
console.log(scriptNames.of("Hans")); // "Simplified Chinese"
console.log(scriptNames.of("Hant")); // "Traditional Chinese"

スクリプト名はユーザーインターフェースではあまり頻繁に表示されませんが、多言語コンテンツ管理システムや表記体系を区別する言語選択インターフェースでは重要になります。

カレンダーコードをカレンダー名に変換する

カレンダーシステムは文化によって異なります。type: "calendar"を設定して、カレンダー識別子をカレンダー名に変換します。

const calendarNames = new Intl.DisplayNames(["en"], { type: "calendar" });

console.log(calendarNames.of("gregory")); // "Gregorian Calendar"
console.log(calendarNames.of("japanese")); // "Japanese Calendar"
console.log(calendarNames.of("buddhist")); // "Buddhist Calendar"
console.log(calendarNames.of("hebrew")); // "Hebrew Calendar"
console.log(calendarNames.of("islamic")); // "Islamic Calendar"
console.log(calendarNames.of("chinese")); // "Chinese Calendar"

これは、スケジュールアプリケーション、カレンダーシステム選択機能付きの日付ピッカー、国際化されたカレンダーインターフェースで役立ちます。

日付と時刻のフィールドコードをフィールド名に変換する

日付と時刻のインターフェースには、年、月、日などのラベル付きフィールドが含まれます。type: "dateTimeField"を設定して、フィールド識別子をローカライズされたフィールド名に変換します。

const dateFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });

console.log(dateFields.of("year")); // "year"
console.log(dateFields.of("month")); // "month"
console.log(dateFields.of("day")); // "day"
console.log(dateFields.of("hour")); // "hour"
console.log(dateFields.of("minute")); // "minute"
console.log(dateFields.of("weekday")); // "day of the week"
console.log(dateFields.of("dayPeriod")); // "AM/PM"
console.log(dateFields.of("timeZoneName")); // "time zone"

これらのフィールド名は表示言語に応じてローカライズされます。

const englishFields = new Intl.DisplayNames(["en"], { type: "dateTimeField" });
const spanishFields = new Intl.DisplayNames(["es"], { type: "dateTimeField" });
const japaneseFields = new Intl.DisplayNames(["ja"], { type: "dateTimeField" });

console.log(englishFields.of("month")); // "month"
console.log(spanishFields.of("month")); // "mes"
console.log(japaneseFields.of("month")); // "月"

有効なフィールド識別子には、erayearquartermonthweekOfYearweekdaydaydayPeriodhourminutesecond、およびtimeZoneNameが含まれます。

このパターンは、適切にローカライズされたラベルを持つアクセシブルな日付ピッカー、カレンダーインターフェース、時刻選択コンポーネントの構築をサポートします。

スタイルオプションによる表示長の制御

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スタイルは、利用可能な場合に省略形を生成しますが、すべてのコードに短縮形があるわけではありません。

スタイルは言語名でより重要になります。

const longLanguages = new Intl.DisplayNames(["en"], {
  type: "language",
  style: "long",
});

const shortLanguages = new Intl.DisplayNames(["en"], {
  type: "language",
  style: "short",
});

console.log(longLanguages.of("en-US")); // "American English"
console.log(shortLanguages.of("en-US")); // "US English"

フォームや詳細なインターフェースでの完全なラベルにはlongを使用してください。モバイルナビゲーションやスペースが限られたUI要素などのコンパクトな表示にはshortまたはnarrowを使用してください。

languageDisplayによる地域言語バリアントの処理

地域サブタグを持つ言語コードは、方言として、または地域修飾子を持つ標準言語名として表示できます。languageDisplayオプションはこの動作を制御し、type: "language"の場合にのみ適用されます。

const dialectNames = new Intl.DisplayNames(["en"], {
  type: "language",
  languageDisplay: "dialect",
});

const standardNames = new Intl.DisplayNames(["en"], {
  type: "language",
  languageDisplay: "standard",
});

console.log(dialectNames.of("nl-BE")); // "Flemish"
console.log(standardNames.of("nl-BE")); // "Dutch (Belgium)"

console.log(dialectNames.of("en-AU")); // "Australian English"
console.log(standardNames.of("en-AU")); // "English (Australia)"

dialect値(デフォルト)は、地域バリアントを一般的な名前を使用して表示します。standard値は、常に基本言語を括弧内の地域修飾子とともに表示します。

地域バリアントにユーザーが認識する有名な名前がある場合はdialectを選択してください。一貫したフォーマットが必要な場合、または一般的でない言語-地域の組み合わせを扱う場合はstandardを選択してください。

無効なコードのフォールバック動作の制御

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("ZZ")); // "ZZ"
console.log(withNoneFallback.of("ZZ")); // undefined

code値(デフォルト)は、表示名が存在しない場合に入力コードを返します。none値は、マッピングされていないコードに対してundefinedを返します。

コード自体にフォールバックする場合でも、表示用の文字列値が常に必要な場合はcodeを使用してください。無効なコードを検出して明示的に処理する必要がある場合はnoneを使用してください。

const regionNames = new Intl.DisplayNames(["en"], {
  type: "region",
  fallback: "none",
});

function getRegionName(code) {
  const name = regionNames.of(code);
  if (name === undefined) {
    return "Unknown region";
  }
  return name;
}

console.log(getRegionName("US")); // "United States"
console.log(getRegionName("INVALID")); // "Unknown region"

国選択コンポーネントの構築

Intl.DisplayNames APIは、インターフェースコンポーネントに直接統合されます。この例では、ユーザーの言語で国名を表示する国選択コンポーネントを構築します。

function CountrySelector({ locale, value, onChange }) {
  const regionNames = new Intl.DisplayNames([locale], { type: "region" });

  const countries = [
    "US",
    "GB",
    "CA",
    "AU",
    "FR",
    "DE",
    "JP",
    "CN",
    "BR",
    "IN",
  ];

  return (
    <select value={value} onChange={(e) => onChange(e.target.value)}>
      <option value="">Select a country</option>
      {countries.map((code) => (
        <option key={code} value={code}>
          {regionNames.of(code)}
        </option>
      ))}
    </select>
  );
}

コンポーネントは、表示言語を制御するlocale propを受け取ります。locale propを変更すると、翻訳された国名でドロップダウンが再レンダリングされます。

言語切り替えコンポーネントの構築

言語切り替えは、各言語を独自の文字体系で表示します。各言語に対してDisplayNamesインスタンスを作成します。

function LanguageSwitcher({ currentLocale, onLocaleChange }) {
  const languages = [
    { code: "en", name: "English" },
    { code: "es", name: "Español" },
    { code: "fr", name: "Français" },
    { code: "de", name: "Deutsch" },
    { code: "ja", name: "日本語" },
    { code: "zh", name: "中文" },
  ];

  return (
    <div>
      {languages.map((lang) => {
        const displayNames = new Intl.DisplayNames([lang.code], {
          type: "language",
        });
        const nativeName = displayNames.of(lang.code);

        return (
          <button
            key={lang.code}
            onClick={() => onLocaleChange(lang.code)}
            className={currentLocale === lang.code ? "active" : ""}
          >
            {nativeName}
          </button>
        );
      })}
    </div>
  );
}

各ボタンは、言語名を独自の文字で表示します。ユーザーは、現在のインターフェース言語に関係なく、自分の言語をすぐに認識できます。

通貨選択コンポーネントの構築

通貨選択は、ローカライズされた通貨名の恩恵を受けます。この例では、表示言語に適応する通貨選択コンポーネントを作成します。

function CurrencySelector({ locale, value, onChange }) {
  const currencyNames = new Intl.DisplayNames([locale], { type: "currency" });

  const currencies = ["USD", "EUR", "GBP", "JPY", "CNY", "CAD", "AUD"];

  return (
    <select value={value} onChange={(e) => onChange(e.target.value)}>
      <option value="">Select currency</option>
      {currencies.map((code) => (
        <option key={code} value={code}>
          {code} - {currencyNames.of(code)}
        </option>
      ))}
    </select>
  );
}

ドロップダウンには、通貨コードとローカライズされた通貨名の両方が表示されます。異なる地域のユーザーは、自分の言語で通貨名を確認できます。

サポートされているすべての値の取得

Intl.supportedValuesOf()メソッドは、各タイプでサポートされているすべての値の配列を返します。これにより、コードのハードコーディングされたリストが不要になります。

const regions = Intl.supportedValuesOf("region");
console.log(regions); // ["AD", "AE", "AF", "AG", "AI", ...]

const languages = Intl.supportedValuesOf("language");
console.log(languages); // ["aa", "ab", "ae", "af", "ak", ...]

const currencies = Intl.supportedValuesOf("currency");
console.log(currencies); // ["AED", "AFN", "ALL", "AMD", ...]

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars); // ["buddhist", "chinese", "coptic", ...]

サポートされているすべての値を自動的に含む動的セレクターを構築します。

function UniversalCountrySelector({ locale, value, onChange }) {
  const regionNames = new Intl.DisplayNames([locale], { type: "region" });
  const allRegions = Intl.supportedValuesOf("region");

  return (
    <select value={value} onChange={(e) => onChange(e.target.value)}>
      <option value="">Select a country</option>
      {allRegions.map((code) => (
        <option key={code} value={code}>
          {regionNames.of(code)}
        </option>
      ))}
    </select>
  );
}

このコンポーネントは、ハードコーディングされたリストを保持することなく、ブラウザでサポートされているすべての地域コードを含みます。

コード形式の要件の理解

各タイプは特定の形式のコードを期待します。誤った形式は、表示名ではなくフォールバック動作を生成します。

地域コードはISO 3166-1 alpha-2(2文字)またはUN M.49(3桁)に従います。

const regionNames = new Intl.DisplayNames(["en"], { type: "region" });

console.log(regionNames.of("US")); // "United States" (ISO 3166-1)
console.log(regionNames.of("001")); // "world" (UN M.49)
console.log(regionNames.of("150")); // "Europe" (UN M.49)

言語コードはBCP 47に従い、ISO 639言語コードとオプションの地域およびスクリプトサブタグを組み合わせます。

const languageNames = new Intl.DisplayNames(["en"], { type: "language" });

console.log(languageNames.of("en")); // "English"
console.log(languageNames.of("en-US")); // "American English"
console.log(languageNames.of("zh-Hans")); // "Simplified Chinese"
console.log(languageNames.of("zh-Hans-CN")); // "Simplified Chinese (China)"

通貨コードはISO 4217(3文字)に従います。

const currencyNames = new Intl.DisplayNames(["en"], { type: "currency" });

console.log(currencyNames.of("USD")); // "US Dollar"
console.log(currencyNames.of("EUR")); // "Euro"

スクリプトコードはISO 15924(4文字、大文字)に従います。

const scriptNames = new Intl.DisplayNames(["en"], { type: "script" });

console.log(scriptNames.of("Latn")); // "Latin"
console.log(scriptNames.of("Arab")); // "Arabic"

コードの比較は大文字と小文字を区別しませんが、標準的な大文字表記に従うことで可読性が向上します。

const regionNames = new Intl.DisplayNames(["en"], { type: "region" });

console.log(regionNames.of("US")); // "United States"
console.log(regionNames.of("us")); // "United States"
console.log(regionNames.of("Us")); // "United States"

ブラウザサポートと互換性

Intl.DisplayNames APIは、2021年にすべての主要ブラウザで利用可能になりました。最新のアプリケーションでは、ポリフィルなしで使用できます。

languageregionscriptcurrencyタイプを含む基本APIは、普遍的なサポートがあります。calendarおよびdateTimeFieldタイプは、後のブラウザバージョンで登場しましたが、2025年時点で広範なサポートがあります。

必要に応じて、実行時に機能サポートを確認します。

if (typeof Intl.DisplayNames !== "undefined") {
  const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
  console.log(regionNames.of("US"));
} else {
  console.log("Intl.DisplayNames not supported");
}

古いブラウザをサポートするアプリケーションの場合、APIが利用できない場合は、静的ルックアップテーブルまたはサードパーティライブラリにフォールバックします。

キャッシングによるパフォーマンスの最適化

DisplayNamesインスタンスの作成はオーバーヘッドが最小限ですが、多数のコードを変換するアプリケーションではインスタンスを再利用する必要があります。

const cache = new Map();

function getDisplayNames(locale, type) {
  const key = `${locale}-${type}`;

  if (!cache.has(key)) {
    cache.set(key, new Intl.DisplayNames([locale], { type }));
  }

  return cache.get(key);
}

function getCountryName(locale, code) {
  const displayNames = getDisplayNames(locale, "region");
  return displayNames.of(code);
}

console.log(getCountryName("en", "US")); // "United States"
console.log(getCountryName("en", "FR")); // "France"
console.log(getCountryName("es", "US")); // "Estados Unidos"

キャッシュは、ロケールとタイプをキーとしてインスタンスを保存します。後続の呼び出しでは、新しいインスタンスを作成するのではなく、既存のインスタンスを再利用します。

このパターンは、ローカライズされたデータの大きなテーブルをレンダリングするなど、数百または数千のコードを変換するホットコードパスで最も重要です。

代替アプローチとの比較

Intl.DisplayNames APIが登場する前は、アプリケーションはコードを名前に変換するためにいくつかのアプローチを使用していました。

ハードコードされたルックアップテーブルはメンテナンスが必要で、事前に決められた言語のみをサポートしていました。

const countryNames = {
  US: "United States",
  GB: "United Kingdom",
  FR: "France",
};

function getCountryName(code) {
  return countryNames[code] || code;
}

このアプローチは、新しい言語を追加する際に破綻します。各言語に個別のルックアップテーブルが必要になるためです。

サードパーティライブラリはローカライゼーションデータを提供しましたが、バンドルサイズが増加しました。

import countries from "i18n-iso-countries";
import countriesEN from "i18n-iso-countries/langs/en.json";
import countriesES from "i18n-iso-countries/langs/es.json";

countries.registerLocale(countriesEN);
countries.registerLocale(countriesES);

console.log(countries.getName("US", "en")); // "United States"
console.log(countries.getName("US", "es")); // "Estados Unidos"

ライブラリはバンドルに数キロバイトのデータを追加し、新しい国が登場したり名前が変更されたりした場合に更新が必要になります。

Intl.DisplayNames APIは両方の問題を解消します。ブラウザがデータを管理することで、データを最新の状態に保ち、バンドルサイズの懸念を排除します。このデータは、追加のダウンロードなしで、ブラウザがサポートするすべての言語をサポートします。