Collation and Sorting by Locale with Intl.Collator

Sort strings correctly for any language using Intl.Collator. Learn about sensitivity levels, numeric sorting, case-first options, and how sort order varies across locales.

Intl.Collator

Detailed Explanation

Intl.Collator: Locale-Aware String Sorting

Default JavaScript string comparison (localeCompare or < / >) does not handle locale-specific sorting rules correctly. Intl.Collator provides proper locale-aware string comparison.

Why Default Sort Fails

// Default sort puts uppercase first, ignores locale rules
['banana', 'Apple', 'cherry'].sort();
// ["Apple", "banana", "cherry"]

// German: ä should sort near 'a', not after 'z'
['äpfel', 'Apfel', 'Banane'].sort();
// ["Apfel", "Banane", "äpfel"] -- wrong!

Locale-Aware Sorting

const de = new Intl.Collator('de');
['äpfel', 'Apfel', 'Banane'].sort(de.compare);
// ["Apfel", "äpfel", "Banane"] -- correct!

const sv = new Intl.Collator('sv');
['äpple', 'apple', 'banana'].sort(sv.compare);
// ["apple", "banana", "äpple"]
// In Swedish, ä sorts AFTER z!

Sensitivity Levels

// "base": a = A = à = À
new Intl.Collator('en', { sensitivity: 'base' })
  .compare('a', 'A');  // 0 (equal)

// "accent": a = A, à ≠ a
new Intl.Collator('en', { sensitivity: 'accent' })
  .compare('a', 'à');  // not 0

// "case": a ≠ A, à = a
new Intl.Collator('en', { sensitivity: 'case' })
  .compare('a', 'A');  // not 0

// "variant": a ≠ A ≠ à ≠ À
new Intl.Collator('en', { sensitivity: 'variant' })
  .compare('a', 'à');  // not 0

Numeric Sorting

// Without numeric: "item10" < "item2" (string comparison)
// With numeric: "item2" < "item10" (number-aware)

const col = new Intl.Collator('en', { numeric: true });
['item10', 'item2', 'item1', 'item20'].sort(col.compare);
// ["item1", "item2", "item10", "item20"]

Case-First Option

// Upper-case first
new Intl.Collator('en', { caseFirst: 'upper' })
['apple', 'Apple', 'APPLE'].sort(col.compare);
// ["APPLE", "Apple", "apple"]

// Lower-case first
new Intl.Collator('en', { caseFirst: 'lower' })
['apple', 'Apple', 'APPLE'].sort(col.compare);
// ["apple", "Apple", "APPLE"]

Performance

Intl.Collator is significantly faster than String.prototype.localeCompare() for sorting large arrays because the collator is created once and reused:

// Slow: creates new collator per comparison
arr.sort((a, b) => a.localeCompare(b, 'de'));

// Fast: reuses single collator
const col = new Intl.Collator('de');
arr.sort(col.compare);

Use Case

Correct sorting is critical for directory listings, contact lists, search result ordering, and any alphabetical display. A German address book must sort names with umlauts correctly. A Swedish application must place characters like 'a' and 'ä' in the right order (they are different letters in Swedish). File managers need numeric sorting so 'file2' appears before 'file10'. Using Intl.Collator ensures strings are sorted according to the user's language expectations.

Try It — Locale String Tester

Open full tool