Introduction to Number Range Formatting
Formatting number ranges is a common requirement in modern web applications, from e-commerce price displays to statistical reporting and data visualization dashboards. The formatRange() method, part of JavaScript's Internationalization API, provides a powerful and locale-aware solution for formatting ranges of numbers without requiring external libraries or custom formatting logic.
What is formatRange()?
The formatRange() method is called on an Intl.NumberFormat instance and formats a range of numbers according to the locale and formatting options configured for that instance. This means you can leverage all the existing formatting options of Intl.NumberFormat -- including currency, percentage, unit display, and precision control -- when formatting number ranges.
MDN's official documentation confirms that this method extends the capabilities of the Internationalization API specifically to handle range formatting.
Modern web development increasingly demands internationalized interfaces that adapt to users' locales and preferences. Whether you're building a global e-commerce platform, a financial dashboard, or a data visualization tool, presenting number ranges in a culturally appropriate format is essential for user experience. The formatRange() method provides this functionality natively, reducing bundle size and ensuring consistent behavior across browsers.
For teams building internationalized web applications, leveraging native APIs like formatRange() reduces dependencies and improves maintainability.
Syntax and Parameters
The formatRange() method accepts two parameters that define the start and end of the range to be formatted.
formatRange(startRange, endRange)
Parameters
| Parameter | Type | Description |
|---|---|---|
startRange | Number, BigInt, or string | The beginning of the number range |
endRange | Number, BigInt, or string | The endpoint of the number range |
The startRange and endRange parameters can accept Number, BigInt, or string values. Strings are parsed in the same way as number conversion, with the important distinction that formatRange() preserves exact values without the potential precision loss that can occur during implicit numeric conversion. This makes it particularly valuable when working with large numbers or values that require exact representation, common in financial applications and scientific data visualization.
The method does not validate whether startRange is less than or equal to endRange, allowing for flexibility in display order but placing the responsibility on the developer to ensure logical range ordering in their applications.
For enterprise JavaScript development, proper type handling and validation are essential for building robust applications that can scale across different use cases.
Return Value and Formatting Behavior
The formatRange() method returns a string representing the formatted range. The formatting behavior is intelligent: the method examines both values and determines which components differ between them.
Approximate Value Indicator
One particularly useful feature is the automatic insertion of an "approximately equals" symbol (represented as "~") when the start and end values would round to the same formatted representation:
const priceFormat = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
maximumFractionDigits: 0
});
console.log(priceFormat.formatRange(2.9, 3.1));
// Output: "~$3"
As documented by MDN Web Docs, the insertion of the approximate symbol depends solely on the locale settings and the formatting options, not on the actual difference between the numeric values. This behavior is consistent across different locales and can be particularly useful when displaying ranges where precision at the displayed level is not meaningful.
This feature is especially valuable in e-commerce applications where price ranges might be shown to users, providing visual clarity about approximate values. When combined with proper SEO optimization, product listings with clear pricing displays can improve user engagement and conversion rates.
Error Handling and Exceptions
The formatRange() method can throw two types of errors that developers should handle appropriately.
RangeError
A RangeError is thrown when either startRange or endRange is NaN (Not a Number) or represents an inconvertible string value.
TypeError
A TypeError is thrown when either parameter is undefined. This differs from other numeric methods that might implicitly convert undefined to NaN or another value, making the behavior explicit and preventing silent failures that could lead to unexpected display results.
Example:
try {
const formatter = new Intl.NumberFormat('en-US');
console.log(formatter.formatRange(undefined, 10));
} catch (e) {
if (e instanceof TypeError) {
console.log('Undefined values are not allowed');
}
}
Best practice for production applications is to validate input values before passing them to formatRange() or to implement try-catch error handling that provides graceful degradation when formatting fails. This is especially important when processing user-generated content or data from external APIs where input validity cannot be guaranteed, common scenarios in full-stack web development.
For AI-powered web applications, robust error handling becomes even more critical when dealing with dynamic data sources and machine learning outputs.
1// Currency Range Formatting2const currencyFormat = new Intl.NumberFormat('en-US', {3 style: 'currency',4 currency: 'USD',5 maximumFractionDigits: 06});7 8console.log(currencyFormat.formatRange(100, 250));9// Output: "$100 - $250"10 11// Percentage Range Formatting12const percentFormat = new Intl.NumberFormat('en-US', {13 style: 'percent',14 minimumFractionDigits: 1,15 maximumFractionDigits: 116});17 18console.log(percentFormat.formatRange(0.25, 0.75));19// Output: "25.0% - 75.0%"20 21// Locale-Specific Formatting22const euroFormat = new Intl.NumberFormat('de-DE', {23 style: 'currency',24 currency: 'EUR'25});26 27console.log(euroFormat.formatRange(50, 100));28// Output: "50 € - 100 €"Browser Compatibility
The formatRange() method achieved Baseline status in 2023, meaning it is supported across all major browser versions released after that point:
| Browser | Support |
|---|---|
| Chrome | 100+ |
| Edge | 100+ |
| Firefox | 115+ |
| Safari | 15.4+ |
According to MDN's compatibility data, this wide support makes formatRange() suitable for production use in modern web applications without requiring polyfills for the majority of users.
Feature Detection
const hasFormatRange = typeof Intl.NumberFormat.prototype.formatRange === 'function';
if (!hasFormatRange) {
// Implement fallback or use polyfill
console.log('formatRange not supported in this browser');
}
For applications requiring support for older browsers, feature detection using the standard approach of checking for the presence of the method on Intl.NumberFormat.prototype can be implemented. A fallback strategy might involve using a simple string concatenation approach or including a polyfill for the method.
Building cross-browser compatible web applications requires understanding which JavaScript features are available across different browser versions and implementing appropriate fallbacks when needed.
Best Practices for Modern Web Development
When incorporating formatRange() into modern web applications, several practices ensure optimal results:
1. Reuse Formatter Instances
Create and reuse Intl.NumberFormat instances rather than creating new instances for each formatting operation:
// Good: Reuse instance
const currencyFormatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
// Bad: Create instance each time
function formatPrice(start, end) {
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
return formatter.formatRange(start, end);
}
2. Consider User Locale Preferences
Set the locales parameter to the user's preferred language:
const userLocale = navigator.language || 'en-US';
const formatter = new Intl.NumberFormat(userLocale, {
style: 'currency',
currency: 'USD'
});
3. Validate Input Before Formatting
Implement proper error handling for robust applications:
function safeFormatRange(formatter, start, end) {
if (typeof start === 'undefined' || typeof end === 'undefined') {
return 'Invalid range';
}
const startNum = Number(start);
const endNum = Number(end);
if (isNaN(startNum) || isNaN(endNum)) {
return 'Invalid numbers';
}
return formatter.formatRange(startNum, endNum);
}
These best practices align with general JavaScript performance optimization techniques and help ensure your applications remain responsive and maintainable. When implementing internationalization at scale, consider how custom web application development can address your specific business requirements while maintaining code quality.
Frequently Asked Questions
What is the difference between format() and formatRange()?
The format() method formats a single number, while formatRange() formats two numbers as a range. formatRange() intelligently determines which components differ between the two values and produces a concise range representation.
Does formatRange() work with BigInt values?
Yes, formatRange() accepts Number, BigInt, or string values for both parameters. This makes it suitable for formatting ranges of very large numbers that exceed the safe integer limit.
How do I customize the range separator?
The range separator is determined by the locale settings. Different locales use different separators (e.g., "-" in en-US, "-" in de-DE). You cannot customize the separator directly through the API.
Can I use formatRange() with compact notation?
Yes, formatRange() respects all formatting options configured on the Intl.NumberFormat instance, including compact notation options.
Sources
- MDN Web Docs - Intl.NumberFormat.prototype.formatRange() - Official JavaScript documentation covering syntax, parameters, examples, and browser compatibility
- MDN Web Docs - Range Interface - DOM Range interface documentation
- MDN Web Docs - Selection getRangeAt() - Selection API reference documentation