Как отображать информацию о валюте в Next.js (Pages Router) v16

Показывайте коды, названия и символы валют

Проблема

Приложения часто нуждаются в отображении информации о валюте без указания фактической цены. Селектор валют может перечислять доступные валюты, документация может ссылаться на обменные курсы, а форма оплаты может показывать, какие валюты принимаются. Просто отображать "USD" непонятно для нетехнических пользователей, а жестко прописывать "доллар США" требует ручного перевода и поддержки. Символы валют, такие как "$", неоднозначны — один и тот же символ используется для обозначения долларов США, Канады и Австралии. Подходящее представление зависит как от контекста, так и от языка пользователя.

Решение

Используйте возможности форматирования react-intl для отображения информации о валюте в формате, соответствующем вашему контексту. Для полных названий валют используйте formatDisplayName с типом валюты, который автоматически локализует такие названия, как "доллар США", на язык пользователя. Для символов используйте Intl.NumberFormat с formatToParts, чтобы извлечь локализованный символ для заданного кода валюты. Для ISO-кодов отображайте код напрямую. Такой подход обеспечивает ясность и правильную локализацию ссылок на валюты без ручной работы по переводу.

Шаги

1. Создайте помощник для извлечения символов валют

Используйте Intl.NumberFormat с formatToParts, чтобы извлечь символ валюты из форматированного числа.

export function getCurrencySymbol(
  currencyCode: string,
  locale: string,
): string {
  const parts = new Intl.NumberFormat(locale, {
    style: "currency",
    currency: currencyCode,
    currencyDisplay: "narrowSymbol",
  }).formatToParts(0);

  const currencyPart = parts.find((part) => part.type === "currency");
  return currencyPart ? currencyPart.value : currencyCode;
}

Опция currencyDisplay управляет формой: "symbol", "narrowSymbol", "code" или "name". Этот помощник возвращает локализованный символ для любого кода валюты.

2. Создайте компонент для отображения валюты

Создайте компонент, который отображает информацию о валюте в разных форматах в зависимости от режима отображения.

import { useIntl } from "react-intl";
import { useRouter } from "next/router";
import { getCurrencySymbol } from "../utils/getCurrencySymbol";

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

export default function CurrencyDisplay({
  currencyCode,
  display,
}: CurrencyDisplayProps) {
  const intl = useIntl();
  const router = useRouter();
  const locale = router.locale || "en";

  if (display === "symbol") {
    const symbol = getCurrencySymbol(currencyCode, locale);
    return <span>{symbol}</span>;
  }

  if (display === "name") {
    const name = intl.formatDisplayName(currencyCode, { type: "currency" });
    return <span>{name}</span>;
  }

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

Метод formatDisplayName с type: 'currency' возвращает локализованное название валюты. Компонент адаптирует свой вывод в зависимости от свойства display.

3. Используйте компонент в разных контекстах

Применяйте компонент отображения валюты там, где нужно показать информацию о валюте без указания цен.

import CurrencyDisplay from "../components/CurrencyDisplay";

export default function PaymentOptions() {
  const acceptedCurrencies = ["USD", "EUR", "GBP", "JPY"];

  return (
    <div>
      <h2>Поддерживаемые валюты</h2>
      <ul>
        {acceptedCurrencies.map((code) => (
          <li key={code}>
            <CurrencyDisplay currencyCode={code} display="name" />
            {" ("}
            <CurrencyDisplay currencyCode={code} display="symbol" />
            {")"}
          </li>
        ))}
      </ul>
    </div>
  );
}

Это отображает локализованные названия валют с их символами, например, "US Dollar ($)" на английском или "Dollar américain ($)" на французском, автоматически адаптируясь к локали пользователя.