Locales & i18n
raqam uses Intl.NumberFormat for all formatting and parsing. You never
hardcode separators — they’re extracted dynamically from the browser’s
internationalization engine.
Basic locale switching
Section titled “Basic locale switching”Pass any BCP 47 locale tag to the locale prop:
// German: 1.234,56<NumberField.Root locale="de-DE" formatOptions={{ style: "currency", currency: "EUR" }} />
// French: 1 234,56 €<NumberField.Root locale="fr-FR" formatOptions={{ style: "currency", currency: "EUR" }} />
// Japanese: ¥1,234<NumberField.Root locale="ja-JP" formatOptions={{ style: "currency", currency: "JPY" }} />Separators, currency symbols, minus signs, and digit systems are all resolved automatically — no configuration needed.
Non-Latin digit systems
Section titled “Non-Latin digit systems”Five locale plugins add support for writing systems that use non-ASCII digits:
| Plugin | Script | Digits | BCP 47 tags |
|---|---|---|---|
raqam/locales/fa | Persian (Extended Arabic-Indic) | ۰۱۲۳۴۵۶۷۸۹ | fa, fa-IR, fa-AF |
raqam/locales/ar | Arabic-Indic | ٠١٢٣٤٥٦٧٨٩ | ar, ar-EG, ar-SA, … |
raqam/locales/hi | Devanagari | ०१२३४५६७८९ | hi, hi-IN, mr, ne |
raqam/locales/bn | Bengali | ০১২৩৪৫৬৭৮৯ | bn, bn-BD, bn-IN |
raqam/locales/th | Thai | ๐๑๒๓๔๕๖๗๘๙ | th, th-TH |
Installing a plugin
Section titled “Installing a plugin”Import the locale plugin once, anywhere in your app (it runs as a side effect):
// app/layout.tsx or src/main.tsximport "raqam/locales/fa"; // adds Persian digit supportimport "raqam/locales/ar"; // adds Arabic-Indic digit supportThen use the locale normally:
<NumberField.Root locale="fa-IR" />Without the plugin, Persian ۱۲۳ typed by the user won’t be normalized. With
the plugin, ۱۲۳ is accepted and internally treated as 123.
All plugins at once
Section titled “All plugins at once”import "raqam/locales"; // imports fa, ar, hi, bn, thEach plugin is only ~100 bytes gzipped.
Locale metadata exports
Section titled “Locale metadata exports”If you want to build locale pickers or feature flags, the bundle entrypoint also re-exports the supported locale lists:
import { FA_LOCALE_CODES, AR_LOCALE_CODES, BN_LOCALE_CODES, HI_LOCALE_CODES, TH_LOCALE_CODES,} from "raqam/locales";These arrays are useful when you want to map a runtime locale to a matching plugin without hardcoding the supported tags yourself.
Lakh/crore grouping
Section titled “Lakh/crore grouping”South Asian locales (hi-IN, bn-BD, mr-IN) use a different grouping
pattern than Western locales (lakhs and crores):
en-US: 10,000,000 (millions)hi-IN: 1,00,00,000 (crores)raqam handles this automatically via Intl.NumberFormat.
RTL locales
Section titled “RTL locales”Arabic, Persian, Hebrew, and Urdu are right-to-left. raqam automatically detects RTL locales and applies the correct rendering. See the RTL guide for details.
Custom digit blocks
Section titled “Custom digit blocks”If you need a digit system not covered by the built-in plugins, register it:
import { registerLocale } from "raqam/core";
// Mongolian digits: ᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙ (U+1810–U+1819)registerLocale({ digitBlocks: [[0x1810, 0x1819]],});Supported locale examples
Section titled “Supported locale examples”const LOCALES = [ { locale: "en-US", label: "English (US)", formatOptions: { style: "currency", currency: "USD" } }, { locale: "de-DE", label: "German", formatOptions: { style: "currency", currency: "EUR" } }, { locale: "fr-FR", label: "French", formatOptions: { style: "currency", currency: "EUR" } }, { locale: "fa-IR", label: "Persian (Iran)", formatOptions: { style: "currency", currency: "IRR" } }, { locale: "ar-EG", label: "Arabic (Egypt)", formatOptions: { style: "currency", currency: "EGP" } }, { locale: "hi-IN", label: "Hindi (India)", formatOptions: { style: "currency", currency: "INR" } }, { locale: "bn-BD", label: "Bengali (Bangladesh)", formatOptions: { style: "currency", currency: "BDT" } }, { locale: "th-TH", label: "Thai", formatOptions: { style: "currency", currency: "THB" } }, { locale: "ja-JP", label: "Japanese", formatOptions: { style: "currency", currency: "JPY" } }, { locale: "zh-CN", label: "Chinese (Simplified)", formatOptions: { style: "currency", currency: "CNY" } },];