Overview
useFormatter() is a composable exported from @bitrix24/b24jssdk. It returns two shared, singleton formatters:
formatterNumber— aFormatterNumbersinstance, a locale-aware wrapper aroundIntl.NumberFormat.formatterIban— aFormatterIbaninstance, pre-loaded with IBAN country specifications: every country from the official IBAN registry, several non-official countries that follow the IBAN structure, and the French regional/administrative subdivisions (GF, GP, MQ, RE, PF, TF, YT, NC, BL, MF, PM).
Both formatters are singletons (FormatterNumbers.getInstance() / FormatterIban.getInstance()), so every call to useFormatter() returns the same underlying instances — state set on one (e.g. a default locale) is visible everywhere else in the app. useFormatter() re-registers the IBAN specifications on every call, but since formatterIban is a singleton and addSpecification just overwrites the map entry for a country code, calling useFormatter() repeatedly is cheap.
import { useFormatter } from '@bitrix24/b24jssdk'
const { formatterNumber, formatterIban } = useFormatter()
console.log(formatterIban.printFormat('GB29NWBK60161331926819'))
// 'GB29 NWBK 6016 1331 9268 19'
console.log(formatterIban.isValid('DE89370400440532013000'))
// true
console.log(formatterNumber.format(1234.567))
// '1,234.57'
Method Signature
useFormatter()
useFormatter(): {
formatterNumber: FormatterNumbers
formatterIban: FormatterIban
}
FormatterNumbers
setDefLocale(locale: string): void
format(value: number, locale?: string): string
FormatterIban
addSpecification(spec: IbanSpecification): void
isValid(iban: string): boolean
printFormat(iban: string, separator?: string): string // default separator ' '
electronicFormat(iban: string): string // strips non-alphanumerics, uppercases
toBBAN(iban: string, separator?: string): string // default separator ' '
fromBBAN(countryCode: string, bban: string): string
isValidBBAN(countryCode: string, bban: string): boolean
Key Concepts
FormatterNumbers.format picks a locale in this order: the explicit locale argument, then the locale set via setDefLocale, then navigator.language (browser only), then falls back to 'en'. Integers are formatted with 0 decimal places, non-integers with exactly 2. When the resolved locale contains 'ru', the decimal comma produced by Intl.NumberFormat is replaced with a dot.FormatterIban.isValid and the BBAN methods (toBBAN, fromBBAN, isValidBBAN) throw Error('No country with code XX') if the IBAN's/BBAN's country code has no registered IbanSpecification. Since useFormatter() already registers every supported country, this only happens for genuinely unsupported or malformed country codes.isValidaccepts loosely formatted input. It runs the IBAN throughelectronicFormatfirst, so spaces and lower-case letters are normalised before the country-specific length, structure, and ISO 7064 MOD 97-10 checksum are verified. Non-string input returnsfalseinstead of throwing.printFormatandtoBBANboth normalise withelectronicFormatfirst, so they accept the same loosely formatted input asisValid.addSpecificationoverwrites by country code. Calling it again for a country already registered (asuseFormatter()does on every call) simply replaces the existingIbanSpecification— it is not cumulative and cannot throw.FormatterNumbersandFormatterIbanare not constructable directly. Both classes guard their constructor and onlygetInstance()can create the singleton; always obtain them throughuseFormatter().
Error Handling
useFormatter() itself never throws. FormatterIban.isValid returns false for malformed or non-string input rather than throwing. The BBAN helpers (toBBAN, fromBBAN, isValidBBAN) and the checksum path throw Error('No country with code XX') only for a country code that has no registered IbanSpecification — which useFormatter() never produces, since it registers every supported country on each call. FormatterNumbers delegates to Intl.NumberFormat, which throws RangeError for an invalid locale or option, not for numeric input.
Examples
Validating and formatting an IBAN:
import { useFormatter } from '@bitrix24/b24jssdk'
const { formatterIban } = useFormatter()
formatterIban.isValid('DE89370400440532013000') // true
formatterIban.isValid('GB29NWBK60161331926818') // false (bad checksum)
formatterIban.printFormat('GB29NWBK60161331926819') // 'GB29 NWBK 6016 1331 9268 19'
formatterIban.printFormat('GB29NWBK60161331926819', '-') // 'GB29-NWBK-6016-1331-9268-19'
// Accepts loosely formatted input (spaces, lower case)
formatterIban.electronicFormat('GB29 NWBK 6016 1331 9268 19') // 'GB29NWBK60161331926819'
Converting between IBAN and BBAN:
import { useFormatter } from '@bitrix24/b24jssdk'
const { formatterIban } = useFormatter()
formatterIban.toBBAN('GB29NWBK60161331926819') // 'NWBK 601613 31926819'
formatterIban.toBBAN('GB29NWBK60161331926819', '-') // 'NWBK-601613-31926819'
formatterIban.isValidBBAN('GB', 'NWBK60161331926819') // true
formatterIban.fromBBAN('GB', 'NWBK60161331926819') // 'GB29NWBK60161331926819'
Locale-aware number formatting:
import { useFormatter } from '@bitrix24/b24jssdk'
const { formatterNumber } = useFormatter()
formatterNumber.format(1234) // '1,234' (integer, 'en' default)
formatterNumber.format(1234.567) // '1,234.57' (rounded to 2 decimals)
formatterNumber.format(1234.5, 'de') // '1.234,50'
formatterNumber.setDefLocale('ru')
formatterNumber.format(1234.5) // '1 234.50' (ru grouping, dot kept instead of comma)
Alternatives and Recommendations
- Use
formatterIban.isValidto check user input before callingprintFormat/toBBAN. Both formatting methods only normalise the string — they do not validate the checksum, so an invalid IBAN can still be "printed" or converted. - Call
useFormatter()once per module/component and destructure what you need. Because both formatters are singletons, there is no benefit to caching the returned object yourself beyond avoiding the destructuring boilerplate. - For plain thousands/decimal formatting without locale awareness, prefer
Text.numberFormat.formatterNumber.formatis locale-aware (viaIntl.NumberFormat) and always rounds non-integers to exactly 2 decimals;Text.numberFormatlets you pick the number of decimals and the separators explicitly, which matches the server-side formatting used elsewhere in Bitrix24 REST payloads. addSpecificationexists mainly for internal use.useFormatter()already registers every supported country on each call;IbanSpecificationitself is not exported from@bitrix24/b24jssdk, so extending the country list from application code is not a supported public workflow today.