JavaScript

JavaScriptのIntl.ListFormat.format():言語に合わせて項目を自然につなぐ

この記事でわかること

Intl.ListFormat.format()で項目を言語に合った文章へつなぐ方法を解説。引数・戻り値、ブラウザーとNode.jsの実行手順、入力の型制約とロケールによる出力差を学べます。

何のために使うのか

選択した商品の名前や参加者を文章に表示するとき、区切り文字だけで配列をつなぐと、言語に合わない表現になることがあります。英語なら末尾に「and」や「or」を入れたい場面があり、項目が1件か複数件かによってもつなぎ方が変わります。

Intl.ListFormat.prototype.format()は、文字列の一覧を指定した言語の規則でつなぐメソッドです。項目数ごとの条件分岐や、接続詞の位置を自分で組み立てる手間を減らせます。商品名、選択肢、対応形式など、人が読む短い一覧を文章へ埋め込む用途に向いています。MDNのメソッド解説

ただし、項目自体を翻訳する機能はありません。日本語の商品名を渡して英語を指定しても、商品名は日本語のままです。表示する名前の翻訳と、名前同士のつなぎ方は別々に用意します。

動作環境とバージョン

このAPIはDOMに依存せず、対応するブラウザーとNode.jsの両方で使えます。外部パッケージのインストールやネットワーク通信は不要です。

MDNでは、Intl.ListFormatとformat()を、2021年4月から主要ブラウザー間で利用できる広く普及した機能として扱っています。本記事では現在のChrome、Edge、Firefox、Safariを対象にします。古いブラウザーや組み込みWebViewでは、実際にAPIが存在するか確認してください。MDNのAPI概要

Node.jsでは、実行環境として公式配布の24系を使用する想定です。これは本記事の手順で使うバージョンであり、APIの導入バージョンを意味するものではありません。Node.jsの公式バイナリーは、国際化処理に必要なICUの完全なデータを含む構成です。独自ビルドでは、Intlが無効だったり、使える言語が限定されたりする場合があります。Node.jsの国際化サポート

APIの存在と言語の対応は別に確認する

Intl.ListFormatが存在しても、必要なロケールのデータまで利用できるとは限りません。後のサンプルでは、APIの有無に加えて、使いたいロケールが対応一覧に含まれるかを確認します。未対応なら処理を止め、異なる言語へ暗黙に切り替わった結果をそのまま表示しない設計です。

引数と戻り値を理解する

まずnew Intl.ListFormat(locales, options)で表示規則を持つオブジェクトを作り、そのformat(list)を呼び出します。

JavaScript
const formatter = new Intl.ListFormat("en-US", {
  type: "conjunction",
  style: "long"
});

console.log(formatter.format(["Apple", "Banana", "Orange"]));

代表的な出力はApple, Banana, and Orangeです。設定はコンストラクターへ、一覧はformat()へ渡すという役割の違いを押さえてください。

表示規則を指定する引数

localesには"ja"や"en-US"などの言語タグを指定します。省略すると実行環境の既定ロケールが使われるため、画面の言語が決まっている場合は明示する方が再現しやすくなります。

optionsで主に使う設定は次のとおりです。

  • type: "conjunction"は、「AとB」のように項目を並べます。既定値です。
  • type: "disjunction"は、「AまたはB」のように選択肢を並べます。
  • type: "unit"は、接続詞を使わず、単位を含む項目などをまとめる用途です。
  • styleには"long"、"short"、"narrow"を指定できます。既定値は"long"です。

短いスタイルを選んでも、長い商品名そのものが省略されるわけではありません。変わるのは主につなぎ方です。また、設定を変えても、言語によっては同じ表示になることがあります。MDNのコンストラクター解説

一覧の引数と戻り値

format(list)のlistには、文字列を要素として持つ反復可能な値を渡します。入門段階では文字列の配列を使うと扱いやすいでしょう。戻り値は整形済みの文字列で、元の配列を書き換える処理ではありません。

空の配列なら空文字列、1件ならその項目だけが返ります。引数の省略も空の一覧として扱われますが、意図を明確にするため、常に配列を渡す書き方を勧めます。

コピーして実行する

次のコードは、APIとロケールの対応を確認してから、英語の列挙、選択肢、空配列、1件だけの一覧を表示します。例外は最後のcatchで受け取り、理由を表示します。

JavaScript
(() => {
  try {
    if (
      typeof Intl === "undefined" ||
      typeof Intl.ListFormat !== "function"
    ) {
      throw new Error("Intl.ListFormatに対応していません");
    }

    const locales = ["en-US", "en-GB"];
    const supported = Intl.ListFormat.supportedLocalesOf(locales, {
      localeMatcher: "lookup"
    });

    if (supported.length !== locales.length) {
      throw new Error("必要な英語ロケールに対応していません");
    }

    const items = ["Apple", "Banana", "Orange"];
    const us = new Intl.ListFormat("en-US", {
      type: "conjunction",
      style: "long"
    });
    const gb = new Intl.ListFormat("en-GB", {
      type: "conjunction",
      style: "long"
    });
    const choice = new Intl.ListFormat("en-US", {
      type: "disjunction",
      style: "long"
    });

    console.log("米国英語: " + us.format(items));
    console.log("英国英語: " + gb.format(items));
    console.log("選択肢: " + choice.format(items));
    console.log("空配列: " + JSON.stringify(us.format([])));
    console.log("1件: " + us.format(["Apple"]));
  } catch (error) {
    const message = error instanceof Error ? error.message : String(error);
    console.error("実行失敗: " + message);
  }
})();

ブラウザーでの実行方法

対応するブラウザーで通常のWebページを開き、開発者ツールのConsoleを選択します。コードブロックの中身全体を貼り付けて実行してください。表示先はページ本文ではなくConsoleです。

全体を即時実行関数で囲んでいるため、同じConsoleで繰り返し実行しても、最上位の変数宣言が衝突しにくい構成です。

Node.jsでの実行方法

公式配布のNode.js 24系を用意し、コードをUTF-8のlist-format.cjsとして保存します。ターミナルでそのファイルがあるディレクトリーへ移動し、次のコマンドを実行してください。

Shell
node --version
node list-format.cjs

最初のコマンドでバージョンを確認し、次のコマンドでサンプルを実行します。コードにimportやrequireはなく、package.jsonの追加設定も不要です。

期待出力

対応するロケールデータを持つ環境では、代表的に次のように表示されます。

CODE
米国英語: Apple, Banana, and Orange
英国英語: Apple, Banana and Orange
選択肢: Apple, Banana, or Orange
空配列: ""
1件: Apple

米国英語では末尾の接続詞の前にもカンマを入れ、英国英語では入れない例をMDNも示しています。ただし、国際化APIの表示結果には実装差が許されます。ここでの出力は公式の例と仕様から導いた期待値で、実機での実行結果ではありません。

失敗例と制約

数値は自動で文字列にならない

配列の要素には文字列が必要です。次のコードは数値を含むため、TypeErrorを捕捉します。

JavaScript
(() => {
  const formatter = new Intl.ListFormat("en-US");

  try {
    console.log(formatter.format(["Apple", 100]));
  } catch (error) {
    console.log(error instanceof TypeError);
  }
})();

APIに対応する環境での期待出力はtrueです。数値を表示したいなら、事前に表示用の文字列へ変換します。オブジェクトをそのまま渡すより、商品名など必要な項目だけを取り出してください。欠損した値を機械的に文字列へ変換すると、画面にundefinedなどが出るため、入力検証も必要です。

無効な設定と未対応言語を区別する

type: "and"のような未定義の設定値はRangeErrorになります。一方、形式として正しい言語タグでも、その環境で未対応なら別のロケールへフォールバックすることがあります。「例外が出なかった」だけでは、意図した言語で表示できたとは判断できません。

戻り値を固定の文字列と比較しない

表示結果には、空白の種類や句読点などの差が生じる可能性があります。format()の結果を固定文字列と比較して業務上の判定に使ったり、保存データの識別子にしたりする用途は避けましょう。判定や保存には元の配列を使い、整形結果は表示用として扱います。

この処理は同期的で、Promiseを返しません。awaitは不要です。また、翻訳、重複の除去、並べ替え、HTMLのエスケープも行いません。必要な処理は整形前後に明示的に組み込みます。

活用事例と導入の進め方

フォームで選択した配送方法、参加者の名前、対応するファイル形式などを、確認画面の短い文章にまとめる用途に適しています。英語画面で「どれか1つ」を表す場合はdisjunction、「すべて」を列挙する場合はconjunctionというように、文章の意味に合わせて設定を選びます。

導入時は、まず1つの表示箇所で、空配列、1件、2件、3件以上を確認すると、件数によるつなぎ方を把握できます。その後、対応する言語ごとに見た目を確認してください。同じ設定で多数の一覧を描画する場合は、作成したフォーマッターを再利用できます。

改善案として、一覧の整形と周囲の文章の翻訳を分けて管理すると保守しやすくなります。たとえば「選択した項目」という見出しは翻訳資源で管理し、項目同士の接続をformat()へ任せます。長い一覧は読みにくくなるため、画面上で何件まで文章として表示するかも別に決めておきましょう。

公式参考資料

仕様と互換性は2026年10月10日時点で、次の公式ドキュメントの本文を確認しています。

PREFERRED SOURCES

Googleの優先するニュース提供元にSEの部屋を追加

Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。

Googleの設定画面で確認する 新しいタブで開きます

候補にSEの部屋が表示されない場合は、まだ追加できません。

y.
WRITTEN BY

y_ymo10

SEの部屋で、HTML・CSSからJavaScript・React・Next.jsまで、Web制作の開発ノートを公開しています。

ほかの開発ノートを読む →