TanStack Start v1で通貨情報を表示する方法

通貨コード、名称、記号の表示

問題

アプリケーションでは、フォーマットされた価格を表示せずに通貨情報を表示する必要がある場合がよくあります。通貨セレクターで利用可能な通貨を一覧表示したり、為替レートに関する記事で特定の通貨をシンボルで参照したり、金融ダッシュボードで通貨コードを表示したりすることがあります。しかし、それぞれの表現方法には制限があります。「USD」のようなISOコードは正確ですが、技術に詳しくないユーザーには分かりにくいです。「US Dollar」のような完全な名称は明確ですが、国際的なユーザー向けには翻訳が必要です。「$」のようなシンボルは馴染みがありますが、曖昧さがあります—同じシンボルが米ドル、カナダドル、オーストラリアドルを表します。コンテキストに合わない形式を選ぶと、明確さが低下し、ユーザーを混乱させる可能性があります。

この課題はローカライゼーションによってさらに複雑になります。英語で機能する通貨名が他の言語では存在しなかったり、不正確だったりする場合があります。ある地域では標準的なシンボルが、別の地域では馴染みがない場合もあります。一貫性のあるロケール対応のアプローチがなければ、アプリケーションは単一言語で通貨表現をハードコードするか、すぐに古くなる大規模な翻訳テーブルを維持することになります。

解決策

ブラウザに組み込まれた国際化APIを使用して、ユーザーのロケールとコンテキストの両方に合った形式で通貨情報を表示します。Intl.DisplayNames APIはローカライズされた完全な通貨名を提供し、currencyDisplayオプションを持つIntl.NumberFormatは通貨シンボルやコードを抽出できます。コンテキストに基づいて適切なAPIと形式オプションを選択することで、翻訳データを維持することなく、通貨の参照が明確かつ適切にローカライズされることを確保します。

通貨コードとロケールを受け取り、適切な表現を返す小さな再利用可能なコンポーネントやヘルパー関数を作成します。このアプローチにより、通貨表示ロジックを一元化し、アプリケーション全体で同じ通貨を異なる形式で簡単に表示できるようになります。

ステップ

1. ローカライズされた通貨名を取得するヘルパーを作成する

Intl.DisplayNames APIをtype: "currency"で使用すると、任意のISO 4217通貨コードに対してローカライズされた完全な通貨名を返します。

export function getCurrencyName(currencyCode: string, locale: string): string {
  const displayNames = new Intl.DisplayNames([locale], { type: "currency" });
  return displayNames.of(currencyCode) || currencyCode;
}

このヘルパーは3文字のISO通貨コードを受け取り、ユーザーの言語で完全な名前を返します。通貨セレクターや説明テキストなど、簡潔さよりも明確さが重要な場合に使用してください。

2. 通貨記号を抽出するヘルパーを作成する

Intl.NumberFormatcurrencyDisplayオプションは通貨の表示方法を制御し、"code"、"symbol"、"narrowSymbol"、"name"の値を持ちます。

export function getCurrencySymbol(
  currencyCode: string,
  locale: string,
  narrow: boolean = false,
): string {
  const formatter = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currencyCode,
    currencyDisplay: narrow ? "narrowSymbol" : "symbol",
  });

  const parts = formatter.formatToParts(0);
  const currencyPart = parts.find((part) => part.type === "currency");
  return currencyPart?.value || currencyCode;
}

このヘルパーはゼロ値をフォーマットし、通貨記号のみを抽出します。narrowパラメータは、「$」のようなコンパクトな記号を使用するか、「US$」のような明確化された記号を使用するかを制御します。テーブルやチャートなどのコンパクトなUI要素で記号を使用してください。

3. 通貨情報を表示するコンポーネントを作成する

displayプロップに基づいて任意のフォーマットで通貨情報をレンダリングできる柔軟なコンポーネントを構築します。

interface CurrencyDisplayProps {
  code: string;
  locale: string;
  display: "name" | "symbol" | "narrowSymbol" | "code";
}

export function CurrencyDisplay({
  code,
  locale,
  display,
}: CurrencyDisplayProps) {
  let content: string;

  if (display === "name") {
    content = getCurrencyName(code, locale);
  } else if (display === "code") {
    content = code.toUpperCase();
  } else {
    content = getCurrencySymbol(code, locale, display === "narrowSymbol");
  }

  return <span>{content}</span>;
}

このコンポーネントは通貨表示ロジックを一元化し、フォーマットの切り替えを容易にします。ドロップダウンや説明テキストには"name"を、コンパクトな表示には"symbol"または"narrowSymbol"を、精度が必要な場合には"code"を使用してください。

4. TanStack Startのルートでコンポーネントを使用する

任意のルートコンポーネントでコンポーネントをインポートして使用し、i18nコンテキストまたはルートローダーからユーザーのロケールを渡します。

import { createFileRoute } from "@tanstack/react-router";
import { CurrencyDisplay } from "~/components/CurrencyDisplay";

export const Route = createFileRoute("/currencies")({
  component: CurrenciesPage,
});

function CurrenciesPage() {
  const locale = "en-US";

  return (
    <div>
      <h1>通貨情報</h1>
      <p>
        正式名称: <CurrencyDisplay code="USD" locale={locale} display="name" />
      </p>
      <p>
        記号: <CurrencyDisplay code="USD" locale={locale} display="symbol" />
      </p>
      <p>
        コード: <CurrencyDisplay code="USD" locale={locale} display="code" />
      </p>
    </div>
  );
}

このコンポーネントは同じ通貨を異なるフォーマットでレンダリングします。実際のアプリケーションでは、i18nプロバイダーまたはルートコンテキストからロケールを取得して、すべての通貨表示がユーザーの言語設定を尊重するようにしてください。