Space after symbol with JS Intl
Asked Answered
I

3

14

I want to format a currency with NumberFormat of Intl and get the returned value with a space " " between the symbol and the number.

new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'USD' }).format(12345)
// "US$12.345,00"
new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'BRL' }).format(12345)
// "R$12.345,00"

What I want: "US$ 12.345,00", "R$ 12.345,00"

Any ideas?

Incantation answered 14/6, 2017 at 1:22 Comment(0)
A
19

You can use replace to further format the currency.

var usd = new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'USD' }).format(12345).replace(/^(\D+)/, '$1 ');

var euro = new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'EUR' }).format(12345).replace(/^(\D+)/, '$1 ');
var deEuro = new Intl.NumberFormat('de', { style: 'currency', currency: 'EUR' }).format(12345).replace(/^(\D+)/, '$1 ');


console.log(usd);
console.log(euro);
console.log(deEuro);

Update

There is currently an issue with Intl.js where some browsers put a space between the currency and the value resulting in the output that OP wanted. In that case, the formatting above will result in 2 spaces (as seen in the comments below).

You can add on .replace(/\s+/g, ' ') to replace multiple spaces with a single space. This will ensure that if a space was added by the browser due to the above issue, the final output will still have a single space as expected.

var usd = new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'USD' }).format(12345).replace(/^(\D+)/, '$1 ').replace(/\s+/, ' ');

var euro = new Intl.NumberFormat('pt-br', { style: 'currency', currency: 'EUR' }).format(12345).replace(/^(\D+)/, '$1 ').replace(/\s+/, ' ');
var deEuro = new Intl.NumberFormat('de', { style: 'currency', currency: 'EUR' }).format(12345).replace(/^(\D+)/, '$1 ').replace(/\s+/, ' ');


console.log(usd);
console.log(euro);
console.log(deEuro);
Anastasio answered 14/6, 2017 at 1:31 Comment(10)
Notice that '$' as second argument in String#replace has special meaning.Mishamishaan
@RobG I updated my answer to take different currencies into account.Anastasio
Does the currency always come before the number?Crawler
@John Hascall Good point. Was assuming currencies before number here.Anastasio
@JohnHascall—do you have an example where it doesn't?Bent
I don't, but I also didn't see that the function specified that it always did, so I wondered ...Crawler
@JohnHascall—Ok, used Wikipedia: "The Cape Verdean escudo places its symbol in the decimal separator position (e.g., 20$00). The usage of many European countries, such as France, Germany, Scandinavian countries, is to place the symbol after the amount 20,50 €.".Bent
Thank @ChavaG! But I wanted a more graceful way. With replace, we can do it: .replace(/^(\D+)/, '$1 ') It attends only if the symbol appears before the number.Incantation
For me, this outputs two spaces: US$ 12.345,00, € 12.345,00 and 12.345,00 €.Queston
This seems to be due to a known issue where some browsers put a space between the currency and the value as seen here. In those browsers, this code will add an additional space. You can add .replace(/\s+/g, ' ') after the original formatting to replace any multiple spaces with a single space. This will ensure that if a space was already added by the browser due to the above issue, you will still be left with a single space.Anastasio
C
2

console.log(formatPrice(1200, 'en-US', 'USD'));
console.log(formatPrice(1200, 'fr-FR', 'EUR'));
  
 
function formatPrice(value, locale, currency) {
  return new Intl.NumberFormat(locale, { style: 'currency', currency })
    .format(value)
    // if the price begins with digit, place the space after the digit
    .replace(/^([\d,.]+)/, '$1 ')
    // if the price ends with digit, place the space before the digit
    .replace(/([\d,.]+)$/, ' $1') 
}
Celebes answered 23/10, 2022 at 23:1 Comment(2)
This question already has a highly upvoted answer. Can you edit your answer to explain what your code does and how it differs from the other answer?Ieshaieso
@MichaelM. The comments in the code explain the contribution, but I agree that this should be elaborated on in the rest of the answer (outside of the code snippet)Queston
D
0
 "use client";
import React from "react";

interface Props {
  value: any; // your type
  className?: string;
}

function Currency({ value, className }: Props) {
  const formatter = new Intl.NumberFormat("en-IN", {
    style: "currency",
    currency: "INR",

    maximumFractionDigits: 3,
  });
  const [symbol, ...others] = formatter.formatToParts(value);
  return (
   

<span className={`flex items-center ${className}`}>
      <span className="currency">{symbol.value} </span>
      <span className="ml-2">{others.map(({ value }) => value).join("")}</span>
    </span>
); } export default Currency;

This approach worked for me :)

Dennison answered 15/3, 2024 at 20:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.