Cómo formatear cantidades monetarias en Next.js (Pages Router) v16
Muestra precios con símbolos de moneda y separadores
Problema
Mostrar valores monetarios requiere coordinar dos aspectos distintos de localización: la moneda en sí y las convenciones de formato numérico de la región del usuario. Un precio de 1200.50 debe aparecer como "$1,200.50" para usuarios de inglés estadounidense, pero como "1 200,50 €" para usuarios en Alemania. La posición del símbolo de moneda, el separador decimal, el separador de agrupación y el espaciado varían según la configuración regional. Cuando estos elementos están desalineados o codificados de forma fija, los usuarios ven formatos poco familiares que generan dudas sobre si la cantidad mostrada es correcta, socavando la confianza en la información de precios.
Más allá de la consistencia visual, el formato incorrecto de moneda puede causar confusión real. Un usuario acostumbrado a las comas como separadores de miles puede interpretar erróneamente "1.200" como uno punto dos, no mil doscientos. De manera similar, un símbolo de moneda mal ubicado puede hacer que los precios parezcan poco profesionales o sugerir una moneda completamente diferente. El formato adecuado de moneda respeta tanto el código de moneda como las convenciones numéricas específicas de la configuración regional del usuario, asegurando que los precios sean inmediatamente claros y confiables.
Solución
Formatea valores de moneda combinando el código de moneda ISO 4217 con la configuración regional activa del usuario para producir un formato numérico apropiado para la región. Este enfoque delega la colocación de símbolos, la selección de separadores y las reglas de espaciado a la biblioteca de internacionalización, que aplica las convenciones correctas para cada par configuración regional-moneda. El resultado es una visualización de precios que coincide con las expectativas del usuario sin manipulación manual de cadenas ni lógica específica de configuración regional en el código de la aplicación.
Pasos
1. Crea un componente reutilizable de formato de moneda
Construye un componente que acepte un valor numérico y un código de moneda, luego formatea el precio usando la configuración regional actual del contexto de react-intl.
import { FormattedNumber } from "react-intl";
interface PriceProps {
value: number;
currency: string;
}
export default function Price({ value, currency }: PriceProps) {
return <FormattedNumber value={value} style="currency" currency={currency} />;
}
El componente FormattedNumber lee la configuración regional del IntlProvider más cercano y aplica automáticamente tanto el símbolo de moneda como las reglas de formato numérico específicas de la configuración regional.
2. Usa el componente en una página con datos de precios dinámicos
Renderiza precios pasando cantidades numéricas y códigos de moneda al componente, permitiendo que el formato se adapte a la configuración regional del usuario.
import { GetServerSideProps } from "next";
import Price from "../components/Price";
interface Product {
id: string;
name: string;
price: number;
currency: string;
}
interface ProductPageProps {
product: Product;
}
export default function ProductPage({ product }: ProductPageProps) {
return (
<div>
<h1>{product.name}</h1>
<p>
<Price value={product.price} currency={product.currency} />
</p>
</div>
);
}
export const getServerSideProps: GetServerSideProps = async () => {
const product = {
id: "1",
name: "Wireless Headphones",
price: 1299.99,
currency: "USD",
};
return {
props: {
product,
},
};
};
La página obtiene los datos del producto incluyendo el código de moneda y los pasa al componente Price, que formatea la cantidad según la configuración regional activa.
3. Crea un helper para formato imperativo de moneda
Para escenarios donde no se puede usar un componente React, como establecer atributos o preparar datos para contextos no JSX, expón una función de formato usando el hook useIntl.
import { useIntl } from "react-intl";
export function useCurrencyFormatter() {
const intl = useIntl();
return (value: number, currency: string): string => {
return intl.formatNumber(value, {
style: "currency",
currency,
});
};
}
Este hook devuelve una función que formatea valores de moneda como cadenas de texto, útil para etiquetas aria, meta tags u otros contextos de solo texto donde los componentes no son apropiados.
4. Aplica el formateador en contextos de atributos
Usa el formateador imperativo para poblar atributos HTML que requieren texto plano en lugar de elementos React.
import { useCurrencyFormatter } from "../hooks/useCurrencyFormatter";
interface ProductCardProps {
name: string;
price: number;
currency: string;
imageUrl: string;
}
export default function ProductCard({
name,
price,
currency,
imageUrl,
}: ProductCardProps) {
const formatCurrency = useCurrencyFormatter();
const priceLabel = formatCurrency(price, currency);
return (
<article aria-label={`${name}, ${priceLabel}`}>
<img src={imageUrl} alt={name} />
<h2>{name}</h2>
<p>{priceLabel}</p>
</article>
);
}
El formateador produce una cadena de moneda localizada que puede ser incrustada en el atributo aria-label, asegurando que las tecnologías de asistencia anuncien los precios en el formato correcto para la configuración regional del usuario.