Formateo de precios

Mostrar formatos de moneda y números localizados

Problema

Mostrar un precio implica tanto un número como una moneda. Un precio en EE. UU. es $1,200.50, mientras que el mismo valor en euros podría ser 1 200,50 € en Alemania. La posición del símbolo de moneda, el separador decimal y el separador de agrupación cambian, y codificar estas reglas para cada idioma es inmanejable.

Solución

Usa el componente FormattedNumber de react-intl con la opción style: 'currency'. Este componente lee la configuración regional actual de su proveedor y formatea un número como precio, manejando automáticamente la ubicación del símbolo, los separadores decimales y la agrupación para esa configuración regional y moneda especificada.

Pasos

1. Crear un componente de cliente para precios

Los componentes de formateo de react-intl deben usarse dentro de componentes de cliente.

Crea un nuevo componente, app/components/ProductPrice.tsx.

// app/components/ProductPrice.tsx
'use client';

import { FormattedNumber } from 'react-intl';

type Props = {
  price: number;
  currencyCode: string; // e.g., "USD", "EUR", "JPY"
};

export default function ProductPrice({ price, currencyCode }: Props) {
  return (
    <FormattedNumber
      value={price}
      style="currency"
      currency={currencyCode}
    />
  );
}

2. Pasar opciones de formateo

El componente FormattedNumber se controla mediante estas props:

  • value: el valor numérico del precio.
  • style: 'currency': esto indica al componente que formatee el número como moneda, no como decimal estándar.
  • currency: el código de moneda ISO de tres letras (por ejemplo, 'USD', 'EUR'). Esto es obligatorio al usar style: 'currency'.

3. Usar el componente en una página

Ahora puedes usar este componente en tus componentes de servidor o cliente para mostrar precios.

// app/[lang]/page.tsx
import ProductPrice from '@/app/components/ProductPrice';

export default function Home() {
  const product = {
    price: 1299.99,
    currency: 'USD',
  };

  const productInEuros = {
    price: 1199.5,
    currency: 'EUR',
  };

  return (
    <div>
      <h1>Product</h1>
      <p>
        Price (USD): <ProductPrice price={product.price} currencyCode={product.currency} />
      </p>
      <p>
        Price (EUR): <ProductPrice price={productInEuros.price} currencyCode={productInEuros.currency} />
      </p>
    </div>
  );
}

Un usuario que visite /en verá "Price (USD): $1,299.99" y "Price (EUR): €1,199.50". Un usuario que visite /es verá "Price (USD): 1299,99 US$" y "Price (EUR): 1199,50 €".